home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / networke / cow / cowl-1.000 / cowl-1 / socket.c < prev    next >
C/C++ Source or Header  |  1994-05-04  |  99KB  |  3,627 lines

  1. /*
  2.  * Socket.c
  3.  * 
  4.  * Kevin P. Smith 1/29/89 UDP stuff v1.0 by Andy McFadden  Feb-Apr 1992
  5.  * 
  6.  * UDP protocol v1.0
  7.  * 
  8.  * Routines to allow connection to the xtrek server.
  9.  */
  10. #include "copyright2.h"
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include <sys/time.h>
  18. #include <netinet/in.h>
  19. #include <netinet/tcp.h>
  20. #include <netdb.h>
  21. #include <arpa/inet.h>
  22. #include <math.h>
  23. #include <errno.h>
  24. #include "Wlib.h"
  25. #include "defs.h"
  26. #include "struct.h"
  27. #include "data.h"
  28. #include "packets.h"
  29.  
  30. #ifdef SHORT_PACKETS
  31. #include "sp.h"
  32. #endif
  33.  
  34. /* #define INCLUDE_SCAN            /* include Amdahl scanning beams */
  35. /* #define INCLUDE_VISTRACT        /* include visible tractor beams */
  36.  
  37. #ifdef GATEWAY
  38. /*
  39.  * (these values are now defined in "main.c":) char *gw_mach        =
  40.  * "charon";     |client gateway; strcmp(serverName) int   gw_serv_port   =
  41.  * 5000;         |what to tell the server to use int   gw_port        = 5001;
  42.  * |where we will contact gw int   gw_local_port  = 5100;         |where we
  43.  * expect gw to contact us
  44.  * 
  45.  * The client binds to "5100" and sends "5000" to the server (TCP).  The server
  46.  * sees that and sends a UDP packet to gw on port udp5000, which passes it
  47.  * through to port udp5100 on the client.  The client-gw gets the server's
  48.  * host and port from recvfrom.  (The client can't use the same method since
  49.  * these sockets are one-way only, so it connect()s to gw_port (udp5001) on
  50.  * the gateway machine regardless of what the server sends.)
  51.  * 
  52.  * So all we need in .gwrc is: udp 5000 5001 tde.uts 5100
  53.  * 
  54.  * assuming the client is on tde.uts.  Note that a UDP declaration will work for
  55.  * ANY server, but you need one per player, and the client has to have the
  56.  * port numbers in advance.
  57.  * 
  58.  * If we're using a standard server, we're set.  If we're running through a
  59.  * gatewayed server, we have to do some unpleasant work on the server side...
  60.  */
  61. #endif
  62.  
  63. int             handleMessage(), handlePhaser(), handlePlyrInfo();
  64. int             handlePlayer(), handleSelf(), handleStatus();
  65. int             handleWarning(), handleTorp(), handleTorpInfo();
  66. int             handlePlanet(), handleQueue(), handlePickok(), handleLogin();
  67. int             handlePlasmaInfo(), handlePlasma();
  68. int             handleKills(), handleFlags(), handlePStatus();
  69. int             handleMotd(), handleMask();
  70. int             handleBadVersion(), handlePlanetLoc();
  71. int             handleHostile(), handleStats(), handlePlyrLogin();
  72. int             handleReserved();
  73. #ifdef RSA
  74. int             handleRSAKey();
  75. #endif
  76. int             handleScan();
  77. int             handleUdpReply(), handleSequence();
  78.  
  79. #ifdef FEATURE
  80. extern int handleFeature ();
  81. extern void reportFeatures ();
  82. #endif
  83.  
  84. #ifdef NEED_EXIT
  85. #ifdef sgi
  86. void            exit(int status);
  87. #else                /* sgi */
  88. int             exit();
  89. #endif                /* sgi */
  90. #endif
  91.  
  92.  
  93.  
  94. extern char    *strcpy_return();
  95.  
  96. #ifdef PING
  97. int             handlePing();    /* ping.c */
  98. #endif
  99.  
  100. #ifdef SHORT_PACKETS
  101. int             handleShortReply(), handleVPlayer(), handleVTorp(), handleSelfShort(),
  102.                 handleSelfShip(), handleVPlanet(), handleSWarning();
  103. int             handleVTorpInfo(), handleSMessage();
  104. static char     numofbits[256] =
  105. {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1,
  106.  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1,
  107.  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
  108.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1,
  109.  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
  110.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
  111.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
  112.  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1,
  113.  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
  114.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
  115.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
  116.  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2,
  117.  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
  118.  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
  119.  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4,
  120.  5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
  121.  
  122. static int      vtsize[9] =
  123. {4, 8, 8, 12, 12, 16, 20, 20, 24};    /* How big is the torppacket */
  124. static int      vtdata[9] =
  125. {0, 3, 5, 7, 9, 12, 14, 16, 18};/* How big is Torpdata */
  126. static int      vtisize[9] =
  127. {4, 7, 9, 11, 13, 16, 18, 20, 22};    /* 4 byte Header + torpdata */
  128.  
  129. int             spwinside = 500;/* WINSIDE from Server */
  130. #define SPWINSIDE 500        /* To make it safe */
  131. LONG            spgwidth = GWIDTH;    /* GWITHT from Server */
  132.  
  133. static
  134. int        my_x, my_y;    /* for rotation we need to keep track of our
  135.                    real coordinates */
  136. #endif /* SHORT_PACKETS */
  137.  
  138. #ifdef PACKET_LOG
  139. int             Log_Packet();
  140. int ALL_BYTES = 0; /* To log all bytes */
  141. #endif
  142.  
  143. struct packet_handler handlers[] =
  144. {
  145.    {0, NULL},            /* record 0 */
  146.    {sizeof(struct mesg_spacket), handleMessage},    /* SP_MESSAGE */
  147.    {sizeof(struct plyr_info_spacket), handlePlyrInfo},    /* SP_PLAYER_INFO */
  148.    {sizeof(struct kills_spacket), handleKills},    /* SP_KILLS */
  149.    {sizeof(struct player_spacket), handlePlayer},    /* SP_PLAYER */
  150.    {sizeof(struct torp_info_spacket), handleTorpInfo},    /* SP_TORP_INFO */
  151.    {sizeof(struct torp_spacket), handleTorp},    /* SP_TORP */
  152.    {sizeof(struct phaser_spacket), handlePhaser},    /* SP_PHASER */
  153.    {sizeof(struct plasma_info_spacket), handlePlasmaInfo},    /* SP_PLASMA_INFO */
  154.    {sizeof(struct plasma_spacket), handlePlasma},    /* SP_PLASMA */
  155.    {sizeof(struct warning_spacket), handleWarning},    /* SP_WARNING */
  156.    {sizeof(struct motd_spacket), handleMotd},    /* SP_MOTD */
  157.    {sizeof(struct you_spacket), handleSelf},    /* SP_YOU */
  158.    {sizeof(struct queue_spacket), handleQueue},    /* SP_QUEUE */
  159.    {sizeof(struct status_spacket), handleStatus},    /* SP_STATUS */
  160.    {sizeof(struct planet_spacket), handlePlanet},    /* SP_PLANET */
  161.    {sizeof(struct pickok_spacket), handlePickok},    /* SP_PICKOK */
  162.    {sizeof(struct login_spacket), handleLogin},    /* SP_LOGIN */
  163.    {sizeof(struct flags_spacket), handleFlags},    /* SP_FLAGS */
  164.    {sizeof(struct mask_spacket), handleMask},    /* SP_MASK */
  165.    {sizeof(struct pstatus_spacket), handlePStatus},    /* SP_PSTATUS */
  166.    {sizeof(struct badversion_spacket), handleBadVersion},    /* SP_BADVERSION */
  167.    {sizeof(struct hostile_spacket), handleHostile},    /* SP_HOSTILE */
  168.    {sizeof(struct stats_spacket), handleStats},    /* SP_STATS */
  169.    {sizeof(struct plyr_login_spacket), handlePlyrLogin},    /* SP_PL_LOGIN */
  170.    {sizeof(struct reserved_spacket), handleReserved},    /* SP_RESERVED */
  171.    {sizeof(struct planet_loc_spacket), handlePlanetLoc},    /* SP_PLANET_LOC */
  172. #ifdef HANDLE_SCAN
  173.    {sizeof(struct scan_spacket), handleScan},    /* SP_SCAN (ATM) */
  174. #else
  175.    {0, NULL},            /* won't be called */
  176. #endif
  177.    {sizeof(struct udp_reply_spacket), handleUdpReply},    /* SP_UDP_STAT */
  178.    {sizeof(struct sequence_spacket), handleSequence},    /* SP_SEQUENCE */
  179.    {sizeof(struct sc_sequence_spacket), handleSequence},    /* SP_SC_SEQUENCE */
  180. #ifdef RSA
  181.    {sizeof(struct rsa_key_spacket), handleRSAKey},    /* SP_RSA_KEY */
  182. #else
  183.    {0, NULL},            /* #31, and exit won't really be called */
  184. #endif
  185.    {0, NULL},            /* 32 */
  186.    {0, NULL},            /* 33 */
  187.    {0, NULL},            /* 34 */
  188.    {0, NULL},            /* 35 */
  189.    {0, NULL},            /* 36 */
  190.    {0, NULL},            /* 37 */
  191.    {0, NULL},            /* 38 */
  192.    {0, NULL},            /* 39 */
  193. #ifdef SHORT_PACKETS
  194.    {sizeof(struct shortreply_spacket), handleShortReply},    /* SP_S_REPLY */
  195.    {-1, handleSMessage},    /* SP_S_MESSAGE */
  196.    {-1 /* sizeof(struct warning_s_spacket) */ , handleSWarning},    /* SP_S_WARNING */
  197.    {sizeof(struct youshort_spacket), handleSelfShort},    /* SP_S_YOU */
  198.    {sizeof(struct youss_spacket), handleSelfShip},    /* SP_S_YOU_SS */
  199.    {-1, /* variable */ handleVPlayer},    /* SP_S_PLAYER */
  200. #else
  201.    {0, NULL},            /* 40 */
  202.    {0, NULL},            /* 41 */
  203.    {0, NULL},            /* 42 */
  204.    {0, NULL},            /* 43 */
  205.    {0, NULL},            /* 44 */
  206.    {0, NULL},            /* 45 */
  207. #endif
  208. #ifdef PING
  209.    {sizeof(struct ping_spacket), handlePing},    /* SP_PING; 46 */
  210. #else
  211.    {0, NULL},            /* 46 */
  212. #endif
  213. #ifdef SHORT_PACKETS
  214.    {-1, /* variable */ handleVTorp},    /* SP_S_TORP; 47 */
  215.    {-1, handleVTorpInfo},    /* SP_S_TORP_INFO; 48 */
  216.    {20, handleVTorp},        /* SP_S_8_TORP; 49 */
  217.    {-1, handleVPlanet},        /* SP_S_PLANET; 50 */
  218. #else
  219.    {0, NULL},            /* 47 */
  220.    {0, NULL},            /* 48 */
  221.    {0, NULL},            /* 49 */
  222.    {0, NULL},            /* 50 */
  223. #endif
  224. #ifdef FEATURE
  225.    {0, NULL},            /* 51 */
  226.    {0, NULL},            /* 52 */
  227.    {0, NULL},            /* 53 */
  228.    {0, NULL},            /* 54 */
  229.    {0, NULL},            /* 55 */
  230.    {0, NULL},            /* 56 */
  231.    {0, NULL},            /* 57 */
  232.    {0, NULL},                   /* 58 */
  233.    {0, NULL},                   /* 59 */
  234.    {sizeof(struct feature_cpacket), handleFeature},    /* CP_FEATURE; 60 */
  235. #endif
  236. };
  237.  
  238. int             sizes[] =
  239. {
  240.    0,                /* record 0 */
  241.    sizeof(struct mesg_cpacket),    /* CP_MESSAGE */
  242.    sizeof(struct speed_cpacket),/* CP_SPEED */
  243.    sizeof(struct dir_cpacket),    /* CP_DIRECTION */
  244.    sizeof(struct phaser_cpacket),    /* CP_PHASER */
  245.    sizeof(struct plasma_cpacket),    /* CP_PLASMA */
  246.    sizeof(struct torp_cpacket),    /* CP_TORP */
  247.    sizeof(struct quit_cpacket),    /* CP_QUIT */
  248.    sizeof(struct login_cpacket),/* CP_LOGIN */
  249.    sizeof(struct outfit_cpacket),    /* CP_OUTFIT */
  250.    sizeof(struct war_cpacket),    /* CP_WAR */
  251.    sizeof(struct practr_cpacket),    /* CP_PRACTR */
  252.    sizeof(struct shield_cpacket),    /* CP_SHIELD */
  253.    sizeof(struct repair_cpacket),    /* CP_REPAIR */
  254.    sizeof(struct orbit_cpacket),/* CP_ORBIT */
  255.    sizeof(struct planlock_cpacket),    /* CP_PLANLOCK */
  256.    sizeof(struct playlock_cpacket),    /* CP_PLAYLOCK */
  257.    sizeof(struct bomb_cpacket),    /* CP_BOMB */
  258.    sizeof(struct beam_cpacket),    /* CP_BEAM */
  259.    sizeof(struct cloak_cpacket),/* CP_CLOAK */
  260.    sizeof(struct det_torps_cpacket),    /* CP_DET_TORPS */
  261.    sizeof(struct det_mytorp_cpacket),    /* CP_DET_MYTORP */
  262.    sizeof(struct copilot_cpacket),    /* CP_COPILOT */
  263.    sizeof(struct refit_cpacket),/* CP_REFIT */
  264.    sizeof(struct tractor_cpacket),    /* CP_TRACTOR */
  265.    sizeof(struct repress_cpacket),    /* CP_REPRESS */
  266.    sizeof(struct coup_cpacket),    /* CP_COUP */
  267.    sizeof(struct socket_cpacket),    /* CP_SOCKET */
  268.    sizeof(struct options_cpacket),    /* CP_OPTIONS */
  269.    sizeof(struct bye_cpacket),    /* CP_BYE */
  270.    sizeof(struct dockperm_cpacket),    /* CP_DOCKPERM */
  271.    sizeof(struct updates_cpacket),    /* CP_UPDATES */
  272.    sizeof(struct resetstats_cpacket),    /* CP_RESETSTATS */
  273.    sizeof(struct reserved_cpacket),    /* CP_RESERVED */
  274. #ifdef INCLUDE_SCAN
  275.    sizeof(struct scan_cpacket),    /* CP_SCAN (ATM) */
  276. #else
  277.    0,
  278. #endif
  279.    sizeof(struct udp_req_cpacket),    /* CP_UDP_REQ */
  280.    sizeof(struct sequence_cpacket),    /* CP_SEQUENCE */
  281. #ifdef RSA
  282.    sizeof(struct rsa_key_cpacket),    /* CP_RSA_KEY */
  283. #else
  284.    0,                /* 37 */
  285. #endif
  286.    0,                /* 38 */
  287.    0,                /* 39 */
  288.    0,                /* 40 */
  289.    0,                /* 41 */
  290. #ifdef PING
  291.    sizeof(struct ping_cpacket),    /* CP_PING_RESPONSE; 42 */
  292. #else
  293.    0,                /* 42 */
  294. #endif
  295. #ifdef SHORT_PACKETS
  296.    sizeof(struct shortreq_cpacket),    /* CP_S_REQ; 43 */
  297.    sizeof(struct threshold_cpacket),    /* CP_S_THRS; 44 */
  298.    -1,                /* CP_S_MESSAGE; 45 */
  299. #else
  300.    0,                           /* 43 */
  301.    0,                /* 44 */
  302.    0,                /* 45 */
  303. #endif
  304. #ifdef FEATURE
  305.    0,                /* 46 */
  306.    0,                /* 47 */
  307.    0,                /* 48 */
  308.    0,                /* 49 */
  309.    0,                /* 50 */
  310.    0,                /* 51 */
  311.    0,                /* 52 */
  312.    0,                /* 53 */
  313.    0,                /* 54 */
  314.    0,                /* 55 */
  315.    0,                /* 56 */
  316.    0,                /* 57 */
  317.    0,                /* 58 */
  318.    0,                /* 59 */
  319.    sizeof (struct feature_cpacket),    /* CP_FEATURE; 60 */
  320. #endif
  321. };
  322.  
  323. #define NUM_PACKETS (sizeof(handlers) / sizeof(handlers[0]) - 1)
  324. #define NUM_SIZES (sizeof(sizes) / sizeof(sizes[0]) - 1)
  325.  
  326.  
  327. #ifdef PACKET_LOG
  328. /*
  329.  * stuff useful for logging server packets to see how much bandwidth * netrek
  330.  * is really using
  331.  */
  332. int             log_packets = 0;/* whether or not to be logging packets */
  333. int             packet_log[NUM_PACKETS];    /* number of packets logged */
  334. int         outpacket_log[NUM_SIZES];
  335. #endif                /* PACKET_LOG */
  336.  
  337. int             serverDead = 0;
  338.  
  339. #define BUFSIZE    3072
  340. char            buf[BUFSIZE];
  341.  
  342. static int      udpLocalPort = 0;
  343. static int      udpServerPort = 0;
  344. static LONG     serveraddr = 0;
  345. static LONG     sequence = 0;
  346. static int      drop_flag = 0;
  347. static int      chan = -1;    /* tells sequence checker where packet is
  348.                  * from */
  349. static short    fSpeed, fDirection, fShield, fOrbit, fRepair, fBeamup,
  350.                 fBeamdown, fCloak, fBomb, fDockperm, fPhaser, fPlasma,
  351.                 fPlayLock, fPlanLock, fTractor, fRepress;
  352. /* reset all the "force command" variables */
  353. resetForce()
  354. {
  355.    fSpeed = fDirection = fShield = fOrbit = fRepair = fBeamup = fBeamdown =
  356.       fCloak = fBomb = fDockperm = fPhaser = fPlasma = fPlayLock = fPlanLock =
  357.       fTractor = fRepress = -1;
  358. }
  359.  
  360. /*
  361.  * If something we want to happen hasn't yet, send it again.
  362.  * 
  363.  * The low byte is the request, the high byte is a max count.  When the max
  364.  * count reaches zero, the client stops trying.  Checking is done with a
  365.  * macro for speed & clarity.
  366.  */
  367. #define FCHECK_FLAGS(flag, force, const) {                      \
  368.         if (force > 0) {                                        \
  369.             if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
  370.                 speedReq.type = const;                          \
  371.                 speedReq.speed = (force & 0xff);                \
  372.                 sendServerPacket(&speedReq);                    \
  373.                 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
  374.                 force -= 0x100;                                 \
  375.                 if (force < 0x100) force = -1;  /* give up */   \
  376.             } else                                              \
  377.                 force = -1;                                     \
  378.         }                                                       \
  379. }
  380. #define FCHECK_VAL(value, force, const) {                       \
  381.         if (force > 0) {                                        \
  382.             if ((value) != (force & 0xff)) {                    \
  383.                 speedReq.type = const;                          \
  384.                 speedReq.speed = (force & 0xff);                \
  385.                 sendServerPacket(&speedReq);                    \
  386.                 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
  387.                 force -= 0x100;                                 \
  388.                 if (force < 0x100) force = -1;  /* give up */   \
  389.             } else                                              \
  390.                 force = -1;                                     \
  391.         }                                                       \
  392. }
  393. #define FCHECK_TRACT(flag, force, const) {                      \
  394.         if (force > 0) {                                        \
  395.             if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
  396.                 tractorReq.type = const;                        \
  397.                 tractorReq.state = ((force & 0xff) >= 0x40);    \
  398.                 tractorReq.pnum = (force & 0xff) & (~0x40);     \
  399.                 sendServerPacket(&tractorReq);                  \
  400.                 V_UDPDIAG(("Forced %d:%d/%d\n", const,          \
  401.                         tractorReq.state, tractorReq.pnum));    \
  402.                 force -= 0x100;                                 \
  403.                 if (force < 0x100) force = -1;  /* give up */   \
  404.             } else                                              \
  405.                 force = -1;                                     \
  406.         }                                                       \
  407. }
  408.  
  409. checkForce()
  410. {
  411.    struct speed_cpacket speedReq;
  412.    struct tractor_cpacket tractorReq;
  413.  
  414.    FCHECK_VAL(me->p_speed, fSpeed, CP_SPEED);    /* almost always repeats */
  415.  
  416. #ifdef nodef            /* not needed */
  417.    FCHECK_VAL(me->p_dir, fDirection, CP_DIRECTION);    /* (ditto) */
  418. #endif
  419.    FCHECK_FLAGS(PFSHIELD, fShield, CP_SHIELD);
  420.    FCHECK_FLAGS(PFORBIT, fOrbit, CP_ORBIT);
  421.    FCHECK_FLAGS(PFREPAIR, fRepair, CP_REPAIR);
  422.    FCHECK_FLAGS(PFBEAMUP, fBeamup, CP_BEAM);
  423.    FCHECK_FLAGS(PFBEAMDOWN, fBeamdown, CP_BEAM);
  424.    FCHECK_FLAGS(PFCLOAK, fCloak, CP_CLOAK);
  425.    FCHECK_FLAGS(PFBOMB, fBomb, CP_BOMB);
  426.    FCHECK_FLAGS(PFDOCKOK, fDockperm, CP_DOCKPERM);
  427.    FCHECK_VAL(phasers[me->p_no].ph_status, fPhaser, CP_PHASER);    /* bug: dir 0 */
  428.    FCHECK_VAL(plasmatorps[me->p_no].pt_status, fPlasma, CP_PLASMA);    /* (ditto) */
  429.    FCHECK_FLAGS(PFPLOCK, fPlayLock, CP_PLAYLOCK);
  430.    FCHECK_FLAGS(PFPLLOCK, fPlanLock, CP_PLANLOCK);
  431.  
  432.    FCHECK_TRACT(PFTRACT, fTractor, CP_TRACTOR);
  433.    FCHECK_TRACT(PFPRESS, fRepress, CP_REPRESS);
  434. }
  435.  
  436. connectToServer(port)
  437.     int             port;
  438. {
  439.    int             s;
  440.    struct sockaddr_in addr;
  441.    struct sockaddr_in naddr;
  442.    int             len;
  443.    fd_set          readfds;
  444.    struct timeval  timeout;
  445.    struct hostent *hp;
  446.    int           optval;
  447.  
  448.    serverDead = 0;
  449.    if (sock != -1) {
  450.       shutdown(sock, 2);
  451.       close(sock);
  452.       sock = -1;
  453.    }
  454. #ifdef nodef
  455.    sleep(3);            /* I think this is necessary for some unknown
  456.                  * reason */
  457. #endif
  458.  
  459.    printf("Waiting for connection (port %d). \n", port);
  460.  
  461.    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  462.       printf("I can't create a socket\n");
  463.       exit(2);
  464.    }
  465.  
  466.    /* allow local address resuse */
  467.    optval = 1;
  468.    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(int)) 
  469.       < 0) {
  470.       perror("setsockopt");
  471.    }
  472.  
  473.    addr.sin_family = AF_INET;
  474.    addr.sin_addr.s_addr = INADDR_ANY;
  475.    addr.sin_port = htons(port);
  476.  
  477.    if (bind(s, &addr, sizeof(addr)) < 0) {
  478. #ifdef nodef
  479.       sleep(10);
  480.       if (bind(s, &addr, sizeof(addr)) < 0) {
  481.      sleep(10);
  482.      if (bind(s, &addr, sizeof(addr)) < 0) {
  483.         printf("I can't bind to port!\n");
  484.         exit(3);
  485.      }
  486.       }
  487. #endif
  488.       perror("bind");    /* NEW */
  489.       exit(1);
  490.    }
  491.    if(listen(s, 1) < 0)
  492.       perror("listen");
  493.  
  494.    len = sizeof(naddr);
  495.  
  496.  tryagain:
  497.    timeout.tv_sec = 240;    /* four minutes */
  498.    timeout.tv_usec = 0;
  499.    FD_ZERO(&readfds);
  500.    FD_SET(s, &readfds);
  501.  
  502.    if(s >= max_fd)
  503.       max_fd = s+1;
  504.  
  505.    if (select(max_fd, &readfds, NULL, NULL, &timeout) == 0) {
  506.       printf("Well, I think the server died!\n");
  507.       exit(0);
  508.    }
  509.  
  510.    sock = accept(s, &naddr, &len);
  511.  
  512.    if (sock == -1) {
  513.       goto tryagain;
  514.    }
  515.  
  516.    if(sock >= max_fd)
  517.       max_fd = sock+1;
  518.  
  519.    printf("Got connection.\n");
  520.  
  521.    close(s);
  522.    pickSocket(port);        /* new socket != port */
  523.  
  524.  
  525.    /*
  526.     * This is necessary; it tries to determine who the caller is,
  527.     * and set "serverName" and "serveraddr" appropriately.
  528.     */
  529.    len = sizeof(struct sockaddr_in);
  530.    if (getpeername(sock, (struct sockaddr *) & addr, &len) < 0) {
  531.       perror("unable to get peername");
  532.       serverName = "nowhere";
  533.    } else {
  534.       serveraddr = addr.sin_addr.s_addr;
  535.       hp = gethostbyaddr((char *) &addr.sin_addr.s_addr, sizeof(LONG), AF_INET);
  536.       if (hp != NULL) {
  537.      serverName = (char *) malloc(strlen(hp->h_name) + 1);
  538.      strcpy(serverName, hp->h_name);
  539.       } else {
  540.      serverName = (char *) malloc(strlen(inet_ntoa(addr.sin_addr)) + 1);
  541.      strcpy(serverName, inet_ntoa(addr.sin_addr));
  542.       }
  543.    }
  544.    printf("Connection from server %s (0x%x)\n", serverName, serveraddr);
  545.  
  546. }
  547.  
  548.  
  549. #ifdef nodef
  550. set_tcp_opts(s)
  551.     int             s;
  552. {
  553.    int             optval = 1;
  554.    struct protoent *ent;
  555.  
  556.    ent = getprotobyname("TCP");
  557.    if (!ent) {
  558.       fprintf(stderr, "TCP protocol not found.\n");
  559.       return;
  560.    }
  561.    if (setsockopt(s, ent->p_proto, TCP_NODELAY, &optval, sizeof(int)) < 0)
  562.                       perror("setsockopt");
  563. }
  564.  
  565. set_udp_opts(s)
  566.     int             s;
  567. {
  568.    int             optval = BUFSIZ;
  569.    struct protoent *ent;
  570.    ent = getprotobyname("UDP");
  571.    if (!ent) {
  572.       fprintf(stderr, "UDP protocol not found.\n");
  573.       return;
  574.    }
  575.    if (setsockopt(s, ent->p_proto, SO_RCVBUF, &optval, sizeof(int)) < 0)
  576.                       perror("setsockopt");
  577. }
  578. #endif
  579.  
  580. callServer(port, server)
  581.     int             port;
  582.     char           *server;
  583. {
  584.    int             s;
  585.    struct sockaddr_in addr;
  586.    struct hostent *hp;
  587.  
  588.    serverDead = 0;
  589.  
  590.    printf("Calling %s on port %d.\n", server, port);
  591.  
  592.    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  593.       printf("I can't create a socket\n");
  594.       exit(0);
  595.    }
  596.    addr.sin_family = AF_INET;
  597.    addr.sin_port = htons(port);
  598.  
  599.    if ((addr.sin_addr.s_addr = inet_addr(server)) == -1) {
  600.       if ((hp = gethostbyname(server)) == NULL) {
  601.      printf("Who is %s?\n", server);
  602.      exit(0);
  603.       } else {
  604.      addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
  605.       }
  606.    }
  607.    serveraddr = addr.sin_addr.s_addr;
  608.  
  609.    if (connect(s, &addr, sizeof(addr)) < 0) {
  610.       printf("Server not listening!\n");
  611.       exit(0);
  612.    }
  613.    printf("Got connection.\n");
  614.  
  615.    sock = s;
  616.  
  617.    if(sock >= max_fd)
  618.       max_fd = sock+1;
  619.  
  620. #ifdef TREKHOPD
  621.    /*
  622.     * We use a different scheme from gw: we tell the server who we want to
  623.     * connect to and what our local UDP port is; it picks its own UDP ports
  624.     * and tells us what they are.  This is MUCH more flexible and avoids a
  625.     * number of problems, and may come in handy if the blessed scheme
  626.     * changes.  It's also slightly more work.
  627.     */
  628.    {
  629.       extern int      port_req, use_trekhopd, serv_port;
  630.       extern char    *host_req;
  631.       struct mesg_cpacket msg;
  632.       struct mesg_spacket reply;
  633.       int             n, count, *ip;
  634.       char           *buf;
  635.  
  636.       if (use_trekhopd) {
  637.      msg.type = SP_MESSAGE;
  638.      msg.group = msg.indiv = msg.pad1 = 0;
  639.      ip = (int *) msg.mesg;
  640.      *(ip++) = htons(port_req);
  641.      *(ip++) = htons(gw_local_port);
  642.      strncpy(msg.mesg + 8, login, 8);
  643.      strcpy(msg.mesg + 16, host_req);
  644.      if (gwrite(s, &msg, sizeof(struct mesg_cpacket)) < 0) {
  645.         fprintf(stderr, "trekhopd init failure\n");
  646.         exit(1);
  647.      }
  648.                      printf("--- trekhopd request sent, awaiting reply\n");
  649.      /* now block waiting for reply */
  650.      count = sizeof(struct mesg_spacket);
  651.      for (buf = (char *) &reply; count; buf += n, count -= n) {
  652.         if ((n = read(s, buf, count)) <= 0) {
  653.            perror("trekhopd read");
  654.            exit(1);
  655.         }
  656.      }
  657.  
  658.      if (reply.type != SP_MESSAGE) {
  659.         fprintf(stderr, "Got bogus reply from trekhopd (%d)\n",
  660.             reply.type);
  661.         exit(1);
  662.      }
  663.      ip = (int *) reply.mesg;
  664.      gw_serv_port = ntohl(*ip++);
  665.      gw_port = ntohl(*ip++);
  666.      serv_port = ntohl(*ip++);
  667.      printf ("--- trekhopd reply received\n");
  668.  
  669.      /* printf("ports = %d/%d, %d\n", gw_serv_port, gw_port, serv_port); */
  670.       }
  671.    }
  672. #endif                /* TREKHOPD */
  673.  
  674.    pickSocket(port);        /* new socket != port */
  675. }
  676.  
  677. isServerDead()
  678. {
  679.    return (serverDead);
  680. }
  681.  
  682. socketPause()
  683. {
  684.    struct timeval  timeout;
  685.    fd_set          readfds;
  686.  
  687.    timeout.tv_sec = 1;
  688.    timeout.tv_usec = 0;
  689.  
  690.    FD_ZERO(&readfds);
  691.    FD_SET(sock, &readfds);
  692.    if (udpSock >= 0)        /* new */
  693.       FD_SET(udpSock, &readfds);
  694.  
  695.    select(max_fd, &readfds, 0, 0, &timeout);
  696. }
  697.  
  698. readFromServer(readfds)
  699.    
  700.    fd_set       *readfds;
  701. {
  702.    int             retval = 0;
  703.  
  704.    if (serverDead)
  705.       return (0);
  706.  
  707.    if(!readfds){
  708.       struct timeval      timeout;
  709.       int        rs;
  710.       fd_set        mask;
  711.  
  712.       readfds = &mask;
  713.  
  714. tryagain:
  715.       FD_ZERO(readfds);
  716.       FD_SET(sock, readfds);
  717.       if (udpSock >= 0)
  718.      FD_SET(udpSock, readfds);
  719.       timeout.tv_sec = 0;
  720.       timeout.tv_usec = 0;
  721.       if ((rs = select(max_fd, readfds, 0, 0, &timeout)) == 0){
  722.      dotimers();
  723.      return 0;
  724.       }
  725.    }
  726.    if (udpSock >= 0 && FD_ISSET(udpSock, readfds)) {
  727.       /* WAS V_ */
  728.       UDPDIAG(("Activity on UDP socket\n"));
  729.       chan = udpSock;
  730.       if (commStatus == STAT_VERIFY_UDP) {
  731.      warning("UDP connection established");
  732.      sequence = 0;    /* reset sequence #s */
  733.      resetForce();
  734.  
  735.      if (udpDebug)
  736.         printUdpInfo();
  737.      UDPDIAG(("UDP connection established.\n"));
  738.  
  739.      commMode = COMM_UDP;
  740.      commStatus = STAT_CONNECTED;
  741.      commSwitchTimeout = 0;
  742.      if (udpClientRecv != MODE_SIMPLE)
  743.         sendUdpReq(COMM_MODE + udpClientRecv);
  744.      if (udpWin) {
  745.         udprefresh(UDP_CURRENT);
  746.         udprefresh(UDP_STATUS);
  747.      }
  748.       }
  749.       retval += doRead(udpSock);
  750.    }
  751.  
  752.    /* Read info from the xtrek server */
  753.    if (FD_ISSET(sock, readfds)) {
  754.       chan = sock;
  755.       if (commMode == COMM_TCP)
  756.      drop_flag = 0;        /* just in case */
  757.       retval += doRead(sock);
  758.    }
  759.  
  760.    dotimers();
  761.    return (retval != 0);    /* convert to 1/0 */
  762. }
  763.  
  764. dotimers()
  765. {
  766.    /* if switching comm mode, decrement timeout counter */
  767.    if (commSwitchTimeout > 0) {
  768.       if (!(--commSwitchTimeout)) {
  769.      /*
  770.       * timed out; could be initial request to non-UDP server (which
  771.       * won't be answered), or the verify packet got lost en route to the
  772.       * server.  Could also be a request for TCP which timed out (weird),
  773.       * in which case we just reset anyway.
  774.       */
  775.      commModeReq = commMode = COMM_TCP;
  776.      commStatus = STAT_CONNECTED;
  777.      if (udpSock >= 0)
  778.         closeUdpConn();
  779.      if (udpWin) {
  780.         udprefresh(UDP_CURRENT);
  781.         udprefresh(UDP_STATUS);
  782.      }
  783.      warning("Timed out waiting for UDP response from server");
  784.      UDPDIAG(("Timed out waiting for UDP response from server\n"));
  785.       }
  786.    }
  787.    /* if we're in a UDP "force" mode, check to see if we need to do something */
  788.    if (udpClientSend > 1 && commMode == COMM_UDP)
  789.       checkForce();
  790. }
  791.  
  792. doRead(asock)
  793.     int             asock;
  794. {
  795.    struct timeval  timeout;
  796.    fd_set          readfds;
  797.    char           *bufptr;
  798.    int             size;
  799.    int             count;
  800.    int             temp;
  801.  
  802.    timeout.tv_sec = 0;
  803.    timeout.tv_usec = 0;
  804.  
  805.    count = read(asock, buf, BUFSIZE - /* space for packet frag */BUFSIZE/4);
  806. #ifdef NETSTAT
  807.    if (netstat && 
  808.        (asock == udpSock || 
  809.     commMode != COMM_UDP ||
  810.     udpClientRecv == MODE_TCP)){
  811.       ns_record_update(count);
  812.    }
  813. #endif
  814.  
  815.    if (debug)
  816.       printf("read %d bytes from %s socket\n",
  817.          count, asock == udpSock ? "UDP" : "TCP");
  818.  
  819.    if (count <= 0) {
  820.       if (asock == udpSock) {
  821.      if (errno == ECONNREFUSED) {
  822.         struct sockaddr_in addr;
  823.  
  824.         UDPDIAG(("asock=%d, sock=%d, udpSock=%d, errno=%d\n",
  825.              asock, sock, udpSock, errno));
  826.         UDPDIAG(("count=%d\n", count));
  827.         UDPDIAG(("Hiccup(%d)!  Reconnecting\n", errno));
  828.         addr.sin_addr.s_addr = serveraddr;
  829.         addr.sin_port = htons(udpServerPort);
  830.         addr.sin_family = AF_INET;
  831.         if (connect(udpSock, &addr, sizeof(addr)) < 0) {
  832.            perror("connect");
  833.            UDPDIAG(("Unable to reconnect\n"));
  834.            /* and fall through to disconnect */
  835.         } else {
  836.            UDPDIAG(("Reconnect successful\n"));
  837.            return (0);
  838.         }
  839.      }
  840.      UDPDIAG(("*** UDP disconnected (res=%d, err=%d)\n",
  841.           count, errno));
  842.      warning("UDP link severed");
  843.      printUdpInfo();
  844.      closeUdpConn();
  845.      commMode = commModeReq = COMM_TCP;
  846.      commStatus = STAT_CONNECTED;
  847.      if (udpWin) {
  848.         udprefresh(UDP_STATUS);
  849.         udprefresh(UDP_CURRENT);
  850.      }
  851.      return (0);
  852.       }
  853.       printf("1) Got read() of %d. Server dead\n", count);
  854.       perror("1) read()");
  855.       serverDead = 1;
  856.       return (0);
  857.    }
  858.    bufptr = buf;
  859.    while (bufptr < buf + count) {
  860.       if (*bufptr < 1 || *bufptr > NUM_PACKETS || handlers[*bufptr].size == 0) {
  861.      int             i;
  862.      fprintf(stderr, "Unknown packet type: %d\n", *bufptr);
  863. #ifndef CORRUPTED_PACKETS
  864.      printf("count: %d, bufptr at %d,  Content:\n", count,
  865.         bufptr - buf);
  866.      for (i = 0; i < count; i++) {
  867.         printf("0x%x, ", (unsigned int) buf[i]);
  868.      }
  869. #endif
  870.      return (0);
  871.       }
  872.       size = handlers[*bufptr].size;
  873. #ifdef SHORT_PACKETS
  874.       if (size == -1) {        /* variable packet */
  875.      switch (*bufptr) {
  876.      case SP_S_MESSAGE:
  877.         size = ((unsigned char) bufptr[4]);    /* IMPORTANT  Changed */
  878.         break;
  879.      case SP_S_WARNING:
  880.         if ((unsigned char) bufptr[1] == STEXTE_STRING ||
  881.         (unsigned char) bufptr[1] == SHORT_WARNING) {
  882.            size = ((unsigned char) bufptr[3]);
  883.         } else
  884.            size = 4;    /* Normal Packet */
  885.         break;
  886.      case SP_S_PLAYER:
  887.         if ((unsigned char) bufptr[1] & (unsigned char) 128) {    /* Small +extended
  888.                                      * Header */
  889.            size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
  890.         } else if ((unsigned char) bufptr[1] & 64) {    /* Small Header */
  891.            size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
  892.         } else {        /* Big Header */
  893.            size = ((unsigned char) bufptr[1] * 4 + 12);
  894.         }
  895.         break;
  896.      case SP_S_TORP:
  897.         size = vtsize[numofbits[(unsigned char) bufptr[1]]];
  898.         break;
  899.      case SP_S_TORP_INFO:
  900.         size = (vtisize[numofbits[(unsigned char) bufptr[1]]] + numofbits[(unsigned char) bufptr[3]]);
  901.         break;
  902.      case SP_S_PLANET:
  903.         size = ((unsigned char) bufptr[1] * VPLANET_SIZE) + 2;
  904.         break;
  905.      default:
  906.         fprintf(stderr, "Unknown variable packet\n");
  907.         /*
  908.         exit(1);
  909.         */
  910.         return 0;
  911.         break;
  912.      }
  913.      if ((size % 4) != 0){
  914.         size += (4 - (size % 4));
  915.      }
  916.      if(size <= 0){
  917.         fprintf(stderr, "Bad short-packet size value (%d)\n", size);
  918.         return 0;
  919.      }
  920.  
  921.      if (debug)
  922.         printf("read variable packet size %d, type %d\n",
  923.            size, *bufptr);
  924.       }
  925. #endif                /* SHORT_PACKETS */
  926.  
  927.       while (size > count + (buf - bufptr)) {
  928.      /*
  929.       * We wait for up to ten seconds for rest of packet. If we don't get
  930.       * it, we assume the server died.
  931.       */
  932. tryagain1:
  933.      timeout.tv_sec = 20;
  934.      timeout.tv_usec = 0;
  935.      FD_ZERO(&readfds);
  936.      FD_SET(asock, &readfds);
  937.      /* readfds=1<<asock; */
  938.      if ((temp=select(max_fd, &readfds, 0, 0, &timeout)) == 0) {
  939.         printf("Packet fragment.  Server must be dead\n");
  940.         serverDead = 1;
  941.         return (0);
  942.      }
  943.      temp = read(asock, buf + count, size - (count + (buf - bufptr)));
  944.      count += temp;
  945.      if (temp <= 0) {
  946.         printf("2) Got read() of %d.  Server is dead\n", temp);
  947.         serverDead = 1;
  948.         return (0);
  949.      }
  950.       }
  951.       if (handlers[*bufptr].handler != NULL) {
  952.      if (asock != udpSock ||
  953.          (!drop_flag || *bufptr == SP_SEQUENCE || *bufptr == SP_SC_SEQUENCE)) {
  954.         if (debug)
  955.            printf("read packet %d\n", *bufptr);
  956. #ifdef RECORD
  957.         if (recordGame && recordFile != NULL && RECORDPACKET(*bufptr))
  958.            if ((fwrite(bufptr, size, 1, recordFile) != 1) ||
  959.            (putc(*bufptr, recordFile) == EOF)) {
  960.           perror("write: (recordFile)");
  961.           fclose(recordFile);
  962.           recordFile = NULL;
  963.            }
  964. #endif
  965.  
  966. #ifdef PACKET_LOG
  967.         if (log_packets)
  968.            (void) Log_Packet((char) (*bufptr), size);
  969. #endif
  970. #ifdef PING
  971.         if (asock == udpSock)
  972.            packets_received++;
  973. #endif
  974.  
  975.         (*(handlers[*bufptr].handler)) (bufptr
  976. #ifdef CORRUPTED_PACKETS
  977.                         ,asock
  978. #endif
  979.            );
  980.      } else{
  981.         if(debug){
  982.            if(drop_flag) printf("%d bytes dropped.\n", size);
  983.         }
  984.         UDPDIAG(("Ignored type %d\n", *bufptr));
  985.      }
  986.       } else {
  987.      printf("Handler for packet %d not installed...\n", *bufptr);
  988.       }
  989.  
  990.       bufptr += size;
  991.  
  992. #ifdef nodef
  993.       if (bufptr > buf + BUFSIZ) {
  994.      bcopy(buf + BUFSIZ, buf, BUFSIZ);
  995.      if (count == BUFSIZ * 2) {
  996. tryagain2:
  997.         FD_ZERO(&readfds);
  998.         FD_SET(asock, &readfds);
  999.         /* readfds = 1<<asock; */
  1000.         if ((temp=select(max_fd, &readfds, 0, 0, &timeout)) > 0) {
  1001.            temp = read(asock, buf + BUFSIZ, BUFSIZ);
  1002.            count = BUFSIZ + temp;
  1003.            if (temp <= 0) {
  1004.           printf("3) Got read() of %d.  Server is dead\n", temp);
  1005.           serverDead = 1;
  1006.           return (0);
  1007.            }
  1008.         } else {
  1009.            count = BUFSIZ;
  1010.         }
  1011.      } else {
  1012.         count -= BUFSIZ;
  1013.      }
  1014.      bufptr -= BUFSIZ;
  1015.       }
  1016. #endif
  1017.    }
  1018.    return (1);
  1019. }
  1020.  
  1021. handleTorp(packet)
  1022.     struct torp_spacket *packet;
  1023. {
  1024.    struct torp    *thetorp;
  1025.  
  1026. #ifdef CORRUPTED_PACKETS
  1027.    if (ntohs(packet->tnum) < 0 || ntohs(packet->tnum) >= MAXPLAYER * MAXTORP) {
  1028.       fprintf(stderr, "handleTorp: bad index %d\n", ntohs(packet->tnum));
  1029.       return;
  1030.    }
  1031. #endif
  1032.  
  1033.  
  1034.    thetorp = &torps[ntohs(packet->tnum)];
  1035.  
  1036.    thetorp->t_x = ntohl(packet->x);
  1037.    thetorp->t_y = ntohl(packet->y);
  1038.    thetorp->t_dir = packet->dir;
  1039.  
  1040. #ifdef ROTATERACE
  1041.    if (rotate) {
  1042.       rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
  1043.            GWIDTH / 2, GWIDTH / 2);
  1044.       rotate_dir(&thetorp->t_dir, rotate_deg);
  1045.    }
  1046. #endif
  1047. #ifdef BD
  1048.    if (bd)
  1049.       bd_test_torp(ntohs(packet->tnum), thetorp);
  1050. #endif
  1051. }
  1052.  
  1053. #ifdef SHORT_PACKETS
  1054.  
  1055. handleVTorp(sbuf)
  1056.     unsigned char  *sbuf;
  1057. {
  1058.    unsigned char  *which, *data;
  1059.    unsigned char   bitset;
  1060.    struct torp    *thetorp;
  1061.    int             dx, dy;
  1062.    int             shiftvar;
  1063.  
  1064.    int             i;
  1065.    register int    shift = 0;    /* How many torps are extracted (for shifting
  1066.                  * ) */
  1067.  
  1068.    /* now we must find the data ... :-) */
  1069.    if (sbuf[0] == SP_S_8_TORP) {/* MAX packet */
  1070.       bitset = 0xff;
  1071.       which = &sbuf[1];
  1072.       data = &sbuf[2];
  1073.    } else {            /* Normal Packet */
  1074.       bitset = sbuf[1];
  1075.       which = &sbuf[2];
  1076.       data = &sbuf[3];
  1077.    }
  1078.  
  1079. #ifdef CORRUPTED_PACKETS
  1080.    /* we probably should do something clever here - jmn */
  1081.    if(*which * 8 >= MAXPLAYER * MAXTORP){
  1082.       fprintf(stderr, "handleVTorp: bad index %d\n", *which * 8);
  1083.       return;
  1084.    }
  1085. #endif
  1086.  
  1087.    thetorp = &torps[((unsigned char) *which * 8)];
  1088.    for (shift = 0, i = 0; /* (unsigned char)bitset != 0 */ i < 8;
  1089.     i++, 
  1090.     thetorp++, 
  1091.     bitset >>= 1) {
  1092.       if (bitset & 01) {
  1093.      dx = (*data >> shift);
  1094.      data++;
  1095.      shiftvar = (unsigned char) *data;    /* to silence gcc */
  1096.      shiftvar <<= (8 - shift);
  1097.      dx |= (shiftvar & 511);
  1098.      shift++;
  1099.      dy = (*data >> shift);
  1100.      data++;
  1101.      shiftvar = (unsigned char) *data;    /* to silence gcc */
  1102.      shiftvar <<= (8 - shift);
  1103.      dy |= (shiftvar & 511);
  1104.      shift++;
  1105.      if (shift == 8) {
  1106.         shift = 0;
  1107.         data++;
  1108.      }
  1109.  
  1110. /* This is necessary because TFREE/TMOVE is now encoded in the bitset */
  1111.  
  1112.      if (thetorp->t_status == TFREE) {
  1113.         thetorp->t_status = TMOVE;    /* guess */
  1114.         players[thetorp->t_owner].p_ntorp++;
  1115.      }
  1116. /* NEW */
  1117.      else if (thetorp->t_owner == me->p_no && thetorp->t_status == TEXPLODE)
  1118.         thetorp->t_status = TMOVE;
  1119.      /* Check if torp is visible */
  1120.      if (dx > SPWINSIDE || dy > SPWINSIDE) {
  1121.         thetorp->t_x = -100000;    /* Not visible */
  1122.         thetorp->t_y = -100000;
  1123.      } else {        /* visible */
  1124.         thetorp->t_x = my_x + ((dx - SPWINSIDE / 2) * SCALE);
  1125.         thetorp->t_y = my_y + ((dy - SPWINSIDE / 2) * SCALE);
  1126. #ifdef ROTATERACE
  1127.         if (rotate) {
  1128.            rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
  1129.            GWIDTH / 2, GWIDTH / 2);
  1130.         }
  1131. #endif
  1132.      }
  1133.       }
  1134.       /* if */ 
  1135.       else {            /* We got a TFREE */
  1136.                             /* tsh */
  1137.      if (thetorp->t_status && 
  1138.          (thetorp->t_status != TEXPLODE)){
  1139.         players[thetorp->t_owner].p_ntorp--;
  1140.         thetorp->t_status = TFREE;    /* That's no guess */
  1141.      }
  1142.       }
  1143.    }                /* for */
  1144. }
  1145. #endif
  1146.  
  1147. handleTorpInfo(packet)
  1148.     struct torp_info_spacket *packet;
  1149. {
  1150.    struct torp    *thetorp;
  1151.  
  1152. #ifdef CORRUPTED_PACKETS
  1153.    if (ntohs(packet->tnum) < 0 || ntohs(packet->tnum) >= MAXPLAYER * MAXTORP) {
  1154.       fprintf(stderr, "handleTorpInfo: bad index %d\n", ntohs(packet->tnum));
  1155.       return;
  1156.    }
  1157. #endif
  1158.  
  1159.    thetorp = &torps[ntohs(packet->tnum)];
  1160.  
  1161.    if (packet->status == TEXPLODE && thetorp->t_status == TFREE) {
  1162.       /* FAT: redundant explosion; don't update p_ntorp */
  1163.       /*
  1164.        * printf("texplode ignored\n");
  1165.        */
  1166.       return;
  1167.    }
  1168.  
  1169.    if (thetorp->t_status == TFREE && packet->status) {
  1170.       players[thetorp->t_owner].p_ntorp++;
  1171. #ifdef nodef
  1172.       if (players[thetorp->t_owner].p_status == PEXPLODE)
  1173.      fprintf(stderr, "TORP STARTED WHEN PLAYER EXPLODED\n");
  1174. #endif
  1175.       /* BORG TEST */
  1176. #ifdef BD
  1177.       if (bd)
  1178.      bd_new_torp(ntohs(packet->tnum), thetorp);
  1179. #endif
  1180.    }
  1181.    if (thetorp->t_status && packet->status == TFREE) {
  1182.       players[thetorp->t_owner].p_ntorp--;
  1183.    }
  1184.    thetorp->t_war = packet->war;
  1185.  
  1186.    if (packet->status != thetorp->t_status) {
  1187.       /* FAT: prevent explosion reset */
  1188.       thetorp->t_status = packet->status;
  1189.       if (thetorp->t_status == TEXPLODE) {
  1190.      thetorp->t_fuse = NUMDETFRAMES;
  1191.       }
  1192.    }
  1193. }
  1194.  
  1195. handleStatus(packet)
  1196.     struct status_spacket *packet;
  1197. {
  1198.    status->tourn = packet->tourn;
  1199.    status->armsbomb = ntohl(packet->armsbomb);
  1200.    status->planets = ntohl(packet->planets);
  1201.    status->kills = ntohl(packet->kills);
  1202.    status->losses = ntohl(packet->losses);
  1203.    status->time = ntohl(packet->time);
  1204.    status->timeprod = ntohl(packet->timeprod);
  1205.  
  1206.    if (debug) {
  1207.       printf("SERVER STATS:\n");
  1208.       printf("time: %d\n", status->time / (60 * 60 * 10));
  1209.       printf("kills: %d\n", status->kills);
  1210.       printf("losses: %d\n", status->losses);
  1211.       printf("planets: %d\n", status->planets);
  1212.       printf("armsbomb: %d\n", status->armsbomb);
  1213.    }
  1214. }
  1215.  
  1216. handleSelf(packet)
  1217.     struct you_spacket *packet;
  1218. {
  1219. #ifdef CORRUPTED_PACKETS
  1220.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  1221.       fprintf(stderr, "handleSelf: bad index %d\n", packet->pnum);
  1222.       return;
  1223.    }
  1224. #endif
  1225.    me = &players[packet->pnum];
  1226.    myship = &(me->p_ship);
  1227.    mystats = &(me->p_stats);
  1228.    me->p_hostile = packet->hostile;
  1229.    me->p_swar = packet->swar;
  1230.    me->p_armies = packet->armies;
  1231.  
  1232. #ifdef nodef
  1233.    if (((me->p_flags & PFGREEN) && (ntohl(packet->flags) & PFRED)) ||
  1234.        ((me->p_flags & PFRED) && (ntohl(packet->flags) & PFGREEN)))
  1235.       printf("green/red transition\n");
  1236. #endif
  1237.  
  1238.    me->p_flags = ntohl(packet->flags);
  1239.    if (me->p_flags & PFPLOCK) {
  1240.       redrawPlayer[me->p_playerl] = 1;
  1241.    }
  1242.    me->p_damage = ntohl(packet->damage);
  1243.    me->p_shield = ntohl(packet->shield);
  1244.    me->p_fuel = ntohl(packet->fuel);
  1245.    me->p_etemp = ntohs(packet->etemp);
  1246.    me->p_wtemp = ntohs(packet->wtemp);
  1247.    me->p_whydead = ntohs(packet->whydead);
  1248.    me->p_whodead = ntohs(packet->whodead);
  1249. #ifdef INCLUDE_VISTRACT
  1250.    if (packet->tractor & 0x40)
  1251.       me->p_tractor = (short) packet->tractor & (~0x40);    /* ATM - visible
  1252.                                  * tractors */
  1253. #ifdef nodef            /* tmp */
  1254.    else
  1255.       me->p_tractor = -1;
  1256. #endif                /* nodef */
  1257. #endif
  1258. }
  1259.  
  1260. #ifdef SHORT_PACKETS
  1261. handleSelfShort(packet)
  1262.     struct youshort_spacket *packet;
  1263. {
  1264.    me = &players[packet->pnum];
  1265.    myship = &(me->p_ship);
  1266.    mystats = &(me->p_stats);
  1267.    me->p_hostile = packet->hostile;
  1268.    me->p_swar = packet->swar;
  1269.    me->p_armies = packet->armies;
  1270.    me->p_flags = ntohl(packet->flags);
  1271.    me->p_whydead = packet->whydead;
  1272.    me->p_whodead = packet->whodead;
  1273. }
  1274.  
  1275. handleSelfShip(packet)
  1276.     struct youss_spacket *packet;
  1277. {
  1278.    int x,y;
  1279.    if (!me)
  1280.       return;            /* wait.. */
  1281.  
  1282.    me->p_damage = ntohs(packet->damage);
  1283.    me->p_shield = ntohs(packet->shield);
  1284.    me->p_fuel = ntohs(packet->fuel);
  1285.    me->p_etemp = ntohs(packet->etemp);
  1286.    me->p_wtemp = ntohs(packet->wtemp);
  1287.  
  1288. /* Heiko told me to undefine this, it's supposed to update ship flags
  1289.    more often?  SRS 3/15/94 */
  1290.    me->p_flags = (me->p_flags & 0xffffff00)|(unsigned char) packet->flags8;
  1291. }
  1292. #endif
  1293.  
  1294. handlePlayer(packet)
  1295.     struct player_spacket *packet;
  1296. {
  1297.    register struct player *pl;
  1298.    int x,y;
  1299.  
  1300. #ifdef CORRUPTED_PACKETS
  1301.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  1302.       fprintf(stderr, "handlePlayer: bad index %d\n", packet->pnum);
  1303.       return;
  1304.    }
  1305. #endif
  1306.  
  1307.  
  1308.    pl = &players[packet->pnum];
  1309.  
  1310.    pl->p_dir = packet->dir;
  1311.  
  1312.    x = htonl(packet->x);
  1313.    y = htonl(packet->y);
  1314.    pl->p_speed = packet->speed;
  1315.  
  1316. #ifdef WARP_DEAD
  1317.   if (dead_warp && pl->p_speed == 14 && x==-10000 && y==-10000) {
  1318.     pl->p_status = PEXPLODE;
  1319.     x = pl->p_x;
  1320.     y = pl->p_y;
  1321.     if (pl->p_dir > DEADPACKETS)
  1322.         pl->p_explode = EX_FRAMES;
  1323.     else 
  1324.         pl->p_explode = 0;
  1325.     redrawPlayer[packet->pnum] = updatePlayer[packet->pnum] = 1;
  1326.   }
  1327. #endif
  1328.  
  1329. #ifdef CLOAK_MAXWARP
  1330.   if (cloak_maxwarp && pl != me) 
  1331.   {
  1332.     if(pl->p_speed == 15)
  1333.       pl->p_flags |= PFCLOAK;
  1334.     else
  1335.       pl->p_flags &= ~(PFCLOAK);
  1336.   }
  1337. #endif
  1338.  
  1339.    pl->p_x = x;
  1340.    pl->p_y = y;
  1341.    redrawPlayer[packet->pnum] = 1;
  1342.  
  1343. #ifdef ROTATERACE
  1344.    if (rotate) {
  1345.       rotate_coord(&pl->p_x, &pl->p_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1346.       rotate_dir(&pl->p_dir, rotate_deg);
  1347.    }
  1348. #endif
  1349. }
  1350.  
  1351. #ifdef SHORT_PACKETS
  1352. handleVPlayer(sbuf)
  1353.     unsigned char  *sbuf;
  1354. {
  1355.    register int    speed, x, y, i, numofplayers, pl_no, save, galactic;
  1356.    unsigned char  *savebuf = sbuf;
  1357.    register struct player *pl;
  1358.    numofplayers = (unsigned char) sbuf[1] & 0x3f;
  1359.  
  1360. #ifdef CORRUPTED_PACKETS
  1361.    /*
  1362.     * should do something clever here - jmn if(pl_no < 0 || pl_no >=
  1363.     * MAXPLAYER){ return; }
  1364.     */
  1365. #endif
  1366.  
  1367. #if MAXPLAYER > 32
  1368.    if (sbuf[1] & (unsigned char) 128) {    /* Short Header + Extended */
  1369.       sbuf += 4;
  1370.       for (i = 0; i < numofplayers; i++) {
  1371.      pl_no = ((unsigned char) *sbuf & 0x1f) + 32;
  1372.      if (pl_no >= MAXPLAYER)
  1373.         continue;        /* a little error check */
  1374.      save = (unsigned char) *sbuf;
  1375.      sbuf++;
  1376.      pl = &players[pl_no];
  1377.  
  1378.      pl->p_speed = (unsigned char) *sbuf & 15;    /* SPEED */
  1379.  
  1380. #ifdef CLOAK_MAXWARP
  1381.      if (cloak_maxwarp && pl != me) {
  1382.     if(pl->p_speed == 15)
  1383.       pl->p_flags |= PFCLOAK;
  1384.     else
  1385.       pl->p_flags &= ~(PFCLOAK);
  1386.   }
  1387. #endif
  1388.      pl->p_dir = (unsigned char) (*sbuf>>4) * 16;    /* realDIR */
  1389.      sbuf++;
  1390.      x = (unsigned char) *sbuf++;
  1391.      y = (unsigned char) *sbuf++;    /* The lower 8 Bits are saved */
  1392.      /* Now we must preprocess the coordinates */
  1393.      if ((unsigned char) save & 64)
  1394.         x |= 256;
  1395.      if ((unsigned char) save & 128)
  1396.         y |= 256;
  1397.  
  1398. #ifdef WARP_DEAD
  1399.      if (dead_warp && pl->speed == 14 && x==-10000 && y==-10000) {
  1400.         pl->p_status = PEXPLODE;
  1401.         x = pl->p_x;
  1402.         y = pl->p_y;
  1403.         if (pl->p_dir > DEADPACKETS)
  1404.         pl->p_explode = EX_FRAMES;
  1405.         else 
  1406.         pl->p_explode = 0;
  1407.         redrawPlayer[pl_no] = updatePlayer[pl_no] = 1;
  1408.      }
  1409. #endif
  1410.      /* Now test if it's galactic or local coord */
  1411.      if (save & 32) {    /* It's galactic */
  1412.  
  1413.         redrawPlayer[pl_no] = 1;
  1414.         if(x == 501 || y == 501){
  1415.            x = -500;
  1416.            y = -500;
  1417.         }
  1418.         pl->p_x = x * (GWIDTH / SPWINSIDE);
  1419.         pl->p_y = y * (GWIDTH / SPWINSIDE);
  1420. #ifdef ROTATERACE
  1421.         if (rotate) {
  1422.            rotate_coord(&pl->p_x, &pl->p_y, 
  1423.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1424.            rotate_dir(&pl->p_dir, rotate_deg);
  1425.         }
  1426. #endif
  1427.      } else {        /* Local */
  1428.         redrawPlayer[pl->p_no] = 1;
  1429.         pl->p_x = my_x + ((x - SPWINSIDE / 2) * SCALE);
  1430.         pl->p_y = my_y + ((y - SPWINSIDE / 2) * SCALE);
  1431. #ifdef ROTATERACE
  1432.         if (rotate) {
  1433.            rotate_coord(&pl->p_x, &pl->p_y, 
  1434.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1435.            rotate_dir(&pl->p_dir, rotate_deg);
  1436.         }
  1437. #endif
  1438.      }
  1439.       }                /* for */
  1440.    }
  1441.    /* if */ 
  1442.    else 
  1443. #endif /* MAXPLAYER > 32 */
  1444.    if (sbuf[1] & 64) {    /* Short Header  */
  1445.       sbuf += 4;
  1446.       for (i = 0; i < numofplayers; i++) 
  1447.       {
  1448.     pl_no = ((unsigned char) *sbuf & 0x1f);
  1449.     if (pl_no >= MAXPLAYER)
  1450.       continue;
  1451.     save = (unsigned char) *sbuf;
  1452.     sbuf++;
  1453.     pl = &players[pl_no];
  1454.  
  1455.     pl->p_speed = (unsigned char) *sbuf & 15;    /* SPEED */
  1456.  
  1457. #ifdef CLOAK_MAXWARP
  1458.     if (cloak_maxwarp && pl != me) {
  1459.     if(pl->p_speed == 15)
  1460.       pl->p_flags |= PFCLOAK;
  1461.     else
  1462.       pl->p_flags &= ~(PFCLOAK);
  1463.   }
  1464. #endif
  1465.      pl->p_dir = (unsigned char) (*sbuf>>4) * 16;    /* realDIR */
  1466.      sbuf++;
  1467.      x = (unsigned char) *sbuf++;
  1468.      y = (unsigned char) *sbuf++;    /* The lower 8 Bits are saved */
  1469.      /* Now we must preprocess the coordinates */
  1470.      if ((unsigned char) save & 64)
  1471.         x |= 256;
  1472.      if ((unsigned char) save & 128)
  1473.         y |= 256;
  1474.  
  1475. #ifdef WARP_DEAD
  1476.      if (dead_warp && pl->p_speed == 14 && x==-10000 && y==-10000) {
  1477.         pl->p_status = PEXPLODE;
  1478.         x = pl->p_x;
  1479.         y = pl->p_y;
  1480.         if (pl->p_dir > DEADPACKETS)
  1481.         pl->p_explode = EX_FRAMES;
  1482.         else 
  1483.         pl->p_explode = 0;
  1484.         redrawPlayer[pl->p_no] = updatePlayer[pl->p_no] = 1;
  1485.      }
  1486. #endif
  1487.      /* Now test if it's galactic or local coord */
  1488.      if (save & 32) {    /* It's galactic */
  1489.         redrawPlayer[pl->p_no] = 1;
  1490.         if(x == 501 || y == 501){
  1491.            x = -500;
  1492.            y = -500;
  1493.         }
  1494.         pl->p_x = x * (GWIDTH / SPWINSIDE);
  1495.         pl->p_y = y * (GWIDTH / SPWINSIDE);
  1496. #ifdef ROTATERACE
  1497.         if (rotate) {
  1498.            rotate_coord(&pl->p_x, &pl->p_y, 
  1499.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1500.            rotate_dir(&pl->p_dir, rotate_deg);
  1501.         }
  1502. #endif
  1503.      } else {        /* Local */
  1504.         redrawPlayer[pl->p_no] = 1;
  1505.         pl->p_x = my_x + ((x - SPWINSIDE / 2) * SCALE);
  1506.         pl->p_y = my_y + ((y - SPWINSIDE / 2) * SCALE);
  1507. #ifdef ROTATERACE
  1508.         if (rotate) {
  1509.            rotate_coord(&pl->p_x, &pl->p_y, 
  1510.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1511.            rotate_dir(&pl->p_dir, rotate_deg);
  1512.         }
  1513. #endif
  1514.      }
  1515.       }                /* for */
  1516.    }
  1517.    /* 2. if */ 
  1518.    else {            /* Big Packet */
  1519.       struct player_s_spacket *packet = (struct player_s_spacket *) sbuf;
  1520.       pl = &players[me->p_no];
  1521.       pl->p_dir = (unsigned char) packet->dir;
  1522.  
  1523.       x = htonl(packet->x);
  1524.       y = htonl(packet->y);
  1525.       pl->p_speed = packet->speed;
  1526.  
  1527. #ifdef WARP_DEAD
  1528.       if (dead_warp && pl->p_speed == 14 && x==-10000 && y==-10000) {
  1529.     pl->p_status = PEXPLODE;
  1530.     x = pl->p_x;
  1531.     y = pl->p_y;
  1532.         if (pl->p_dir > DEADPACKETS)
  1533.             pl->p_explode = EX_FRAMES;
  1534.         else 
  1535.             pl->p_explode = 0;
  1536.     redrawPlayer[me->p_no] = updatePlayer[me->p_no] = 1;
  1537.       }
  1538. #endif
  1539.  
  1540.  
  1541. #ifdef CLOAK_MAXWARP
  1542.   if (cloak_maxwarp && pl != me) 
  1543.   {
  1544.     if(pl->p_speed == 15)
  1545.       pl->p_flags |= PFCLOAK;
  1546.     else
  1547.       pl->p_flags &= ~(PFCLOAK);
  1548.   }
  1549. #endif
  1550.       pl->p_x = my_x = x;
  1551.       pl->p_y = my_y = y;
  1552. #ifdef ROTATERACE
  1553.       if (rotate) {
  1554.      rotate_coord(&pl->p_x, &pl->p_y, 
  1555.         rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1556.      rotate_dir(&pl->p_dir, rotate_deg);
  1557.       }
  1558. #endif
  1559.       redrawPlayer[me->p_no] = 1;
  1560.  
  1561.       if (sbuf[1] == 0)
  1562.      return;
  1563.       sbuf += 12;        /* Now the small packets */
  1564.       for (i = 0; i < numofplayers; i++) {
  1565.      pl_no = ((unsigned char) *sbuf & 0x1f);
  1566.      if (pl_no >= MAXPLAYER)
  1567.         continue;
  1568.      save = (unsigned char) *sbuf;
  1569.      sbuf++;
  1570.      pl = &players[pl_no];
  1571.  
  1572.  
  1573.      pl->p_speed = (unsigned char) *sbuf & 15;    /* SPEED */
  1574.  
  1575. #ifdef CLOAK_MAXWARP
  1576.      if (cloak_maxwarp && pl != me) {
  1577.     if(pl->p_speed == 15)
  1578.       pl->p_flags |= PFCLOAK;
  1579.     else
  1580.       pl->p_flags &= ~(PFCLOAK);
  1581.   }
  1582. #endif
  1583.      pl->p_dir = (unsigned char) (*sbuf>>4) * 16;    /* realDIR */
  1584.      sbuf++;
  1585.      x = (unsigned char) *sbuf++;
  1586.      y = (unsigned char) *sbuf++;    /* The lower 8 Bits are saved */
  1587.      /* Now we must preprocess the coordinates */
  1588.      if ((unsigned char) save & 64)
  1589.         x |= 256;
  1590.      if ((unsigned char) save & 128)
  1591.         y |= 256;
  1592. #ifdef WARP_DEAD
  1593.      if (dead_warp && pl->p_speed == 14 && x==-10000 && y==-10000) {
  1594.          pl->p_status = PEXPLODE;
  1595.          x = pl->p_x;
  1596.          y = pl->p_y;
  1597.          if (pl->p_dir > DEADPACKETS)
  1598.         pl->p_explode = EX_FRAMES;
  1599.          else 
  1600.         pl->p_explode = 0;
  1601.          redrawPlayer[pl_no] = updatePlayer[pl_no] = 1;
  1602.      }
  1603. #endif
  1604.      /* Now test if it's galactic or local coord */
  1605.      if (save & 32) {    /* It's galactic */
  1606.         redrawPlayer[pl_no] = 1;
  1607.         if(x == 501 || y == 501){
  1608.            x = -500;
  1609.            y = -500;
  1610.         }
  1611.         pl->p_x = x * (GWIDTH / SPWINSIDE);
  1612.         pl->p_y = y * (GWIDTH / SPWINSIDE);
  1613. #ifdef ROTATERACE
  1614.         if (rotate) {
  1615.            rotate_coord(&pl->p_x, &pl->p_y, 
  1616.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1617.            rotate_dir(&pl->p_dir, rotate_deg);
  1618.         }
  1619. #endif
  1620.      } else {        /* Local */
  1621.         redrawPlayer[pl_no] = 1;
  1622.         pl->p_x = my_x + (x - SPWINSIDE / 2) * SCALE;
  1623.         pl->p_y = my_y + (y - SPWINSIDE / 2) * SCALE;
  1624. #ifdef ROTATERACE
  1625.         if (rotate) {
  1626.            rotate_coord(&pl->p_x, &pl->p_y, 
  1627.           rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1628.            rotate_dir(&pl->p_dir, rotate_deg);
  1629.         }
  1630. #endif
  1631.      }
  1632.       }                /* for */
  1633.    }
  1634. }
  1635.  
  1636. #endif                /* SHORT_PACKETS */
  1637.  
  1638. handleWarning(packet)
  1639.     struct warning_spacket *packet;
  1640. {
  1641.    packet->mesg[sizeof(packet->mesg) - 1] = '\0';    /* guarantee null
  1642.                              * termination */
  1643.    warning(packet->mesg);
  1644. }
  1645.  
  1646. sendShortPacket(type, state)
  1647.     char            type, state;
  1648. {
  1649.    struct speed_cpacket speedReq;
  1650.  
  1651.    speedReq.type = type;
  1652.    speedReq.speed = state;
  1653.    sendServerPacket((struct player_spacket *) & speedReq);
  1654.  
  1655.    /* if we're sending in UDP mode, be prepared to force it */
  1656.    if (commMode == COMM_UDP && udpClientSend >= 2) {
  1657.       switch (type) {
  1658.       case CP_SPEED:
  1659.      fSpeed = state | 0x100;
  1660.      break;
  1661.       case CP_DIRECTION:
  1662.      fDirection = state | 0x100;
  1663.      break;
  1664.       case CP_SHIELD:
  1665.      fShield = state | 0xa00;
  1666.      break;
  1667.       case CP_ORBIT:
  1668.      fOrbit = state | 0xa00;
  1669.      break;
  1670.       case CP_REPAIR:
  1671.      fRepair = state | 0xa00;
  1672.      break;
  1673.       case CP_CLOAK:
  1674.      fCloak = state | 0xa00;
  1675.      break;
  1676.       case CP_BOMB:
  1677.      fBomb = state | 0xa00;
  1678.      break;
  1679.       case CP_DOCKPERM:
  1680.      fDockperm = state | 0xa00;
  1681.      break;
  1682.       case CP_PLAYLOCK:
  1683.      fPlayLock = state | 0xa00;
  1684.      break;
  1685.       case CP_PLANLOCK:
  1686.      fPlanLock = state | 0xa00;
  1687.      break;
  1688.       case CP_BEAM:
  1689.      if (state == 1)
  1690.         fBeamup = 1 | 0x500;
  1691.      else
  1692.         fBeamdown = 2 | 0x500;
  1693.      break;
  1694.       }
  1695.  
  1696.       /* force weapons too? */
  1697.       if (udpClientSend >= 3) {
  1698.      switch (type) {
  1699.      case CP_PHASER:
  1700.         fPhaser = state | 0x100;
  1701.         break;
  1702.      case CP_PLASMA:
  1703.         fPlasma = state | 0x100;
  1704.         break;
  1705.      }
  1706.       }
  1707.    }
  1708. }
  1709.  
  1710. sendServerPacket(packet)
  1711.     /* Pick a random type for the packet */
  1712.     struct player_spacket *packet;
  1713. {
  1714.    int             size;
  1715.  
  1716.    if (serverDead)
  1717.       return;
  1718.    if (packet->type < 1 || packet->type > NUM_SIZES || sizes[packet->type] == 0) {
  1719.       printf("Attempt to send strange packet %d!\n", packet->type);
  1720.       return;
  1721.    }
  1722.    size = sizes[packet->type];
  1723. #ifdef PACKET_LOG
  1724.    if (log_packets)
  1725.       Log_OPacket(packet->type,size);
  1726. #endif
  1727.    if (commMode == COMM_UDP) {
  1728.       /* for now, just sent everything via TCP */
  1729.    }
  1730.    if (commMode == COMM_TCP || !udpClientSend) {
  1731.       /* special case for verify packet */
  1732.       if (packet->type == CP_UDP_REQ) {
  1733.      if (((struct udp_req_cpacket *) packet)->request == COMM_VERIFY)
  1734.         goto send_udp;
  1735.       }
  1736.       /*
  1737.        * business as usual (or player has turned off UDP transmission)
  1738.        */
  1739.       if (gwrite(sock, (char *) packet, size) != size) {
  1740.      printf("gwrite failed.  Server must be dead\n");
  1741.      serverDead = 1;
  1742.       }
  1743.    } else {
  1744.       /*
  1745.        * UDP stuff
  1746.        */
  1747.       switch (packet->type) {
  1748.       case CP_SPEED:
  1749.       case CP_DIRECTION:
  1750.       case CP_PHASER:
  1751.       case CP_PLASMA:
  1752.       case CP_TORP:
  1753.       case CP_QUIT:
  1754.       case CP_PRACTR:
  1755.       case CP_SHIELD:
  1756.       case CP_REPAIR:
  1757.       case CP_ORBIT:
  1758.       case CP_PLANLOCK:
  1759.       case CP_PLAYLOCK:
  1760.       case CP_BOMB:
  1761.       case CP_BEAM:
  1762.       case CP_CLOAK:
  1763.       case CP_DET_TORPS:
  1764.       case CP_DET_MYTORP:
  1765.       case CP_REFIT:
  1766.       case CP_TRACTOR:
  1767.       case CP_REPRESS:
  1768.       case CP_COUP:
  1769.       case CP_DOCKPERM:
  1770. #ifdef INCLUDE_SCAN
  1771.       case CP_SCAN:
  1772. #endif
  1773. #ifdef PING
  1774.       case CP_PING_RESPONSE:
  1775. #endif
  1776.      /* non-critical stuff, use UDP */
  1777.        send_udp:
  1778. #ifdef PING
  1779.      packets_sent++;
  1780. #endif
  1781.  
  1782.      V_UDPDIAG(("Sent %d on UDP port\n", packet->type));
  1783.      if (gwrite(udpSock, packet, size) != size) {
  1784.         UDPDIAG(("gwrite on UDP failed.  Closing UDP connection\n"));
  1785.         warning("UDP link severed");
  1786.         /* serverDead=1; */
  1787.         commModeReq = commMode = COMM_TCP;
  1788.         commStatus = STAT_CONNECTED;
  1789.         commSwitchTimeout = 0;
  1790.         if (udpWin) {
  1791.            udprefresh(UDP_STATUS);
  1792.            udprefresh(UDP_CURRENT);
  1793.         }
  1794.         if (udpSock >= 0)
  1795.            closeUdpConn();
  1796.      }
  1797.      break;
  1798.  
  1799.       default:
  1800.      /* critical stuff, use TCP */
  1801.      if (gwrite(sock, (char *) packet, size) != size) {
  1802.         printf("gwrite failed.  Server must be dead\n");
  1803.         serverDead = 1;
  1804.      }
  1805.       }
  1806.    }
  1807. }
  1808.  
  1809. handlePlanet(packet)
  1810.     struct planet_spacket *packet;
  1811. {
  1812.    struct planet  *plan;
  1813.    /* FAT: prevent excessive redraw */
  1814.    int             redraw = 0;
  1815.  
  1816. #ifdef CORRUPTED_PACKETS
  1817.    if (packet->pnum < 0 || packet->pnum >= MAXPLANETS) {
  1818.       fprintf(stderr, "handlePlanet: bad index %d\n", packet->pnum);
  1819.       return;
  1820.    }
  1821. #endif
  1822.  
  1823.    plan = &planets[packet->pnum];
  1824.  
  1825. #ifdef nodef
  1826.    monpoprate(plan, packet);
  1827. #endif
  1828.  
  1829.    if (plan->pl_owner != packet->owner)
  1830.       redraw = 1;
  1831.    plan->pl_owner = packet->owner;
  1832.    if (plan->pl_owner < FED || plan->pl_owner > ORI)
  1833.       plan->pl_owner = NOBODY;
  1834.    if (plan->pl_info != packet->info)
  1835.       redraw = 1;
  1836.    plan->pl_info = packet->info;
  1837.    /* Redraw the planet because it was updated by server */
  1838.  
  1839.    if (plan->pl_flags != (int) ntohs(packet->flags))
  1840.       redraw = 1;
  1841.    plan->pl_flags = (int) ntohs(packet->flags);
  1842.  
  1843.    if (plan->pl_armies != ntohl(packet->armies)) {
  1844. #ifdef EM
  1845.       /*
  1846.        * don't redraw when armies change unless it crosses the '4' * army
  1847.        * limit. Keeps people from watching for planet 'flicker' * when
  1848.        * players are beaming
  1849.        */
  1850.       int             planetarmies = ntohl(packet->armies);
  1851.       if ((plan->pl_armies < 5 && planetarmies > 4) ||
  1852.       (plan->pl_armies > 4 && planetarmies < 5))
  1853. #endif
  1854.      redraw = 1;
  1855.    }
  1856.    plan->pl_armies = ntohl(packet->armies);
  1857.    if (plan->pl_info == 0) {
  1858.       plan->pl_owner = NOBODY;
  1859.    }
  1860.    if (redraw){
  1861.  
  1862.       plan->pl_flags |= (PLREDRAW|PLCLEAR);
  1863.    }
  1864. }
  1865.  
  1866. handlePhaser(packet)
  1867.     struct phaser_spacket *packet;
  1868. {
  1869.    struct phaser  *phas;
  1870.  
  1871. #ifdef CORRUPTED_PACKETS
  1872.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  1873.       fprintf(stderr, "handlePhaser: bad index %d\n", packet->pnum);
  1874.       return;
  1875.    }
  1876.    if (packet->status == PHHIT &&
  1877.        (ntohl(packet->target) < 0 || ntohl(packet->target) >= MAXPLAYER)) {
  1878.       fprintf(stderr, "handlePhaser: bad target %d\n", ntohl(packet->target));
  1879.       return;
  1880.    }
  1881. #endif
  1882.  
  1883.    phas = &phasers[packet->pnum];
  1884.    phas->ph_status = packet->status;
  1885.    phas->ph_dir = packet->dir;
  1886.    phas->ph_x = ntohl(packet->x);
  1887.    phas->ph_y = ntohl(packet->y);
  1888.    phas->ph_target = ntohl(packet->target);
  1889.    phas->ph_fuse = 0;        /* NEW */
  1890.  
  1891. #ifdef ROTATERACE
  1892.    if (rotate) {
  1893.       rotate_coord(&phas->ph_x, &phas->ph_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
  1894.       rotate_dir(&phas->ph_dir, rotate_deg);
  1895.    }
  1896. #endif
  1897. }
  1898.  
  1899. handleMessage(packet)
  1900.     struct mesg_spacket *packet;
  1901. {
  1902.    if (packet->m_from >= MAXPLAYER)
  1903.       packet->m_from = 255;
  1904.  
  1905. #ifdef CORRUPTED_PACKETS
  1906.    packet->mesg[sizeof(packet->mesg) - 1] = '\0';
  1907. #endif
  1908.  
  1909.    /*
  1910.     * printf("flags: 0x%x\n", packet->m_flags); printf("from: %d\n",
  1911.     * packet->m_from); printf("recpt: %d\n", packet->m_recpt); printf("mesg:
  1912.     * %s\n", packet->mesg);
  1913.     */
  1914.  
  1915.  
  1916.    dmessage(packet->mesg, packet->m_flags, packet->m_from, packet->m_recpt);
  1917. }
  1918.  
  1919. #ifdef SHORT_PACKETS
  1920. handleSMessage(packet)
  1921.     struct mesg_s_spacket *packet;
  1922. {
  1923.    char            buf[100], *bf = buf;
  1924.    char            addrbuf[9];
  1925.    unsigned char   flags;
  1926.  
  1927.    if (debug)
  1928.       printf("Length of Message is: %d  total Size %d \n", strlen(&packet->mesg), (int) packet->length);
  1929.    if (packet->m_from >= MAXPLAYER)
  1930.       packet->m_from = 255;
  1931.  
  1932.    if (packet->m_from == 255){
  1933.       strcpy(bf, "GOD->");
  1934.       bf += 5;
  1935.    }
  1936.    else {
  1937.       *bf++ = ' ';
  1938.       *bf++ = teamlet[players[packet->m_from].p_team];
  1939.       *bf++ = shipnos[players[packet->m_from].p_no];
  1940.       *bf++ = '-';
  1941.       *bf++ = '>';
  1942.    }
  1943.  
  1944.    switch (packet->m_flags & (MTEAM | MINDIV | MALL)) {
  1945.    case MALL:
  1946.       bf = strcpy_return(bf, "ALL");
  1947.       break;
  1948.    case MTEAM:
  1949.       bf = strcpy_return(bf, teamshort[me->p_team]);
  1950.       break;
  1951.    case MINDIV:
  1952.       /* I know that it's me -> xxx but i copied it straight ... */
  1953.       *bf++ = teamlet[players[packet->m_recpt].p_team];
  1954.       *bf++ = shipnos[packet->m_recpt];
  1955.       break;
  1956.    default:
  1957.       bf = strcpy_return (bf, "ALL");
  1958.       break;
  1959.    }
  1960.    while(bf-buf < 9)
  1961.       *bf++ = ' ';
  1962.    strcpy(bf, &packet->mesg);
  1963.    dmessage(buf, packet->m_flags, packet->m_from, packet->m_recpt);
  1964. }
  1965. #endif                /* SHORT_PACKETS */
  1966.  
  1967. handleQueue(packet)
  1968.     struct queue_spacket *packet;
  1969. {
  1970.    queuePos = ntohs(packet->pos);
  1971. }
  1972.  
  1973. sendTeamReq(team, ship)
  1974.     int             team, ship;
  1975. {
  1976.    struct outfit_cpacket outfitReq;
  1977.  
  1978.    outfitReq.type = CP_OUTFIT;
  1979.    outfitReq.team = team;
  1980.    outfitReq.ship = ship;
  1981.    sendServerPacket((struct player_spacket *) & outfitReq);
  1982. }
  1983.  
  1984. handlePickok(packet)
  1985.     struct pickok_spacket *packet;
  1986. {
  1987.    pickOk = packet->state;
  1988. }
  1989.  
  1990. sendLoginReq(name, pass, login, query)
  1991.     char           *name, *pass;
  1992.     char           *login;
  1993.     char            query;
  1994. {
  1995.    struct login_cpacket packet;
  1996.  
  1997.    strcpy(packet.name, name);
  1998.    strcpy(packet.password, pass);
  1999.    if (strlen(login) > 15)
  2000.       login[15] = 0;
  2001.    strcpy(packet.login, login);
  2002.    packet.type = CP_LOGIN;
  2003.    packet.query = query;
  2004.    sendServerPacket((struct player_spacket *) & packet);
  2005. }
  2006.  
  2007. handleLogin(packet)
  2008.     struct login_spacket *packet;
  2009. {
  2010.    loginAccept = packet->accept;
  2011.    
  2012.    if ((packet->pad2 == 69) && (packet->pad3 == 42))
  2013.    {
  2014.      printf ("Connection Error: this client does not support parardise server protocols.\n");
  2015.      exit(0);
  2016.    }
  2017.    
  2018.    if (packet->accept) {
  2019.       /*
  2020.        * no longer needed .. we have it in xtrekrc bcopy(packet->keymap,
  2021.        * mystats->st_keymap, 96);
  2022.        */
  2023.       mystats->st_flags = ntohl(packet->flags);
  2024.       showShields = (me->p_stats.st_flags / ST_SHOWSHIELDS) & 1;
  2025. #ifndef nodef
  2026.       mapmode = (me->p_stats.st_flags / ST_MAPMODE) & 1;
  2027. #endif
  2028.       namemode = (me->p_stats.st_flags / ST_NAMEMODE) & 1;
  2029.       keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1;
  2030.       showlocal = (me->p_stats.st_flags / ST_SHOWLOCAL) & 3;
  2031.       showgalactic = (me->p_stats.st_flags / ST_SHOWGLOBAL) & 3;
  2032.    }
  2033. }
  2034.  
  2035. sendTractorReq(state, pnum)
  2036.     char            state;
  2037.     char            pnum;
  2038. {
  2039.    struct tractor_cpacket tractorReq;
  2040.  
  2041.    tractorReq.type = CP_TRACTOR;
  2042.    tractorReq.state = state;
  2043.    tractorReq.pnum = pnum;
  2044.    sendServerPacket((struct player_spacket *) & tractorReq);
  2045.  
  2046.    if (state)
  2047.       fTractor = pnum | 0x40;
  2048.    else
  2049.       fTractor = 0;
  2050. }
  2051.  
  2052. sendRepressReq(state, pnum)
  2053.     char            state;
  2054.     char            pnum;
  2055. {
  2056.    struct repress_cpacket repressReq;
  2057.  
  2058.    repressReq.type = CP_REPRESS;
  2059.    repressReq.state = state;
  2060.    repressReq.pnum = pnum;
  2061.    sendServerPacket((struct player_spacket *) & repressReq);
  2062.  
  2063.    if (state)
  2064.       fRepress = pnum | 0x40;
  2065.    else
  2066.       fRepress = 0;
  2067. }
  2068.  
  2069. sendDetMineReq(torp)
  2070.     short           torp;
  2071. {
  2072.    struct det_mytorp_cpacket detReq;
  2073.  
  2074.    detReq.type = CP_DET_MYTORP;
  2075.    detReq.tnum = htons(torp);
  2076.    sendServerPacket((struct player_spacket *) & detReq);
  2077. }
  2078.  
  2079. handlePlasmaInfo(packet)
  2080.     struct plasma_info_spacket *packet;
  2081. {
  2082.    struct plasmatorp *thetorp;
  2083.  
  2084. #ifdef CORRUPTED_PACKETS
  2085.    if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA) {
  2086.       fprintf(stderr, "handlePlasmaInfo: bad index %d\n", packet->pnum);
  2087.       return;
  2088.    }
  2089. #endif
  2090.  
  2091.    thetorp = &plasmatorps[ntohs(packet->pnum)];
  2092.    if (packet->status == PTEXPLODE && thetorp->pt_status == PTFREE) {
  2093.       /* FAT: redundant explosion; don't update p_nplasmatorp */
  2094.       return;
  2095.    }
  2096.    if (!thetorp->pt_status && packet->status) {
  2097.       players[thetorp->pt_owner].p_nplasmatorp++;
  2098.    }
  2099.    if (thetorp->pt_status && !packet->status) {
  2100.       players[thetorp->pt_owner].p_nplasmatorp--;
  2101.    }
  2102.    thetorp->pt_war = packet->war;
  2103.    if (thetorp->pt_status != packet->status) {
  2104.       /* FAT: prevent explosion timer from being reset */
  2105.       thetorp->pt_status = packet->status;
  2106.       if (thetorp->pt_status == PTEXPLODE) {
  2107.      thetorp->pt_fuse = NUMDETFRAMES;
  2108.       }
  2109.    }
  2110. }
  2111.  
  2112. handlePlasma(packet)
  2113.     struct plasma_spacket *packet;
  2114. {
  2115.    struct plasmatorp *thetorp;
  2116. #ifdef CORRUPTED_PACKETS
  2117.    if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA) {
  2118.       fprintf(stderr, "handlePlasma: bad index %d\n", packet->pnum);
  2119.       return;
  2120.    }
  2121. #endif
  2122.    thetorp = &plasmatorps[ntohs(packet->pnum)];
  2123.    thetorp->pt_x = ntohl(packet->x);
  2124.    thetorp->pt_y = ntohl(packet->y);
  2125.  
  2126. #ifdef ROTATERACE
  2127.    if (rotate) {
  2128.       rotate_coord(&thetorp->pt_x, &thetorp->pt_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
  2129.    }
  2130. #endif
  2131. }
  2132.  
  2133. handleFlags(packet)
  2134.     struct flags_spacket *packet;
  2135. {
  2136. #ifdef CORRUPTED_PACKETS
  2137.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2138.       fprintf(stderr, "handleFlags: bad index %d\n", packet->pnum);
  2139.       return;
  2140.    }
  2141. #endif
  2142.    if (players[packet->pnum].p_flags != ntohl(packet->flags)
  2143. #ifdef INCLUDE_VISTRACT
  2144.        || players[packet->pnum].p_tractor !=
  2145.        ((short) packet->tractor & (~0x40))
  2146. #endif
  2147.       ) {
  2148.       /* FAT: prevent redundant player update */
  2149.       redrawPlayer[packet->pnum] = 1;
  2150.    } else
  2151.       return;
  2152.  
  2153.    players[packet->pnum].p_flags = ntohl(packet->flags);
  2154. #ifdef INCLUDE_VISTRACT
  2155.    if (packet->tractor & 0x40)
  2156.       players[packet->pnum].p_tractor = (short) packet->tractor & (~0x40);    /* ATM - visible
  2157.                                          * tractors */
  2158.    else
  2159. #endif                /* INCLUDE_VISTRACT */
  2160.       players[packet->pnum].p_tractor = -1;
  2161. }
  2162.  
  2163. handleKills(packet)
  2164.     struct kills_spacket *packet;
  2165. {
  2166. #ifdef CORRUPTED_PACKETS
  2167.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2168.       fprintf(stderr, "handleKills: bad index %d\n", packet->pnum);
  2169.       return;
  2170.    }
  2171. #endif
  2172.    if (players[packet->pnum].p_kills != ntohl(packet->kills) / 100.0) {
  2173.       players[packet->pnum].p_kills = ntohl(packet->kills) / 100.0;
  2174.       /* FAT: prevent redundant player update */
  2175.       updatePlayer[packet->pnum] = 1;
  2176. #ifdef ARMY_SLIDER
  2177.       if (me == &players[packet->pnum]) {
  2178.      calibrate_stats();
  2179.      redrawStats();
  2180.       }
  2181. #endif                /* ARMY_SLIDER */
  2182.    }
  2183. }
  2184.  
  2185. handlePStatus(packet)
  2186.     struct pstatus_spacket *packet;
  2187. {
  2188.    register struct player    *j;
  2189. #ifdef CORRUPTED_PACKETS
  2190.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2191.       fprintf(stderr, "handlePStatus: bad index %d\n", packet->pnum);
  2192.       return;
  2193.    }
  2194. #endif
  2195.    j = &players[packet->pnum];
  2196.    if(packet->status == j->p_status) return;
  2197.  
  2198.    /* guarantees we won't miss the kill message since this is TCP */
  2199.    if(packet->status == PALIVE && j->p_status != PALIVE)
  2200.       j->p_kills = 0.;
  2201.  
  2202.    updatePlayer[packet->pnum] = 1;
  2203.  
  2204.    if (packet->status == PEXPLODE) {
  2205.       j->p_explode = 0;
  2206.    }
  2207.    /*
  2208.     * Ignore DEAD status. Instead, we treat it as PEXPLODE. This gives us
  2209.     * time to animate all the frames necessary for the explosions at our own
  2210.     * pace.
  2211.     */
  2212.    if (packet->status == PDEAD) {
  2213.       packet->status = PEXPLODE;
  2214.    }
  2215.    j->p_status = packet->status;
  2216.    redrawPlayer[packet->pnum] = 1;
  2217. }
  2218.  
  2219. handleMotd(packet)
  2220.     struct motd_spacket *packet;
  2221. {
  2222.    packet->line[sizeof(packet->line) - 1] = '\0';
  2223.    newMotdLine(packet->line);
  2224. }
  2225.  
  2226. sendMessage(mes, group, indiv)
  2227.     char           *mes;
  2228.     int             group, indiv;
  2229. {
  2230.    struct mesg_cpacket mesPacket;
  2231. #ifdef SHORT_PACKETS
  2232.    if (recv_short) {
  2233.       int             size;
  2234.       size = strlen(mes);
  2235.       size += 5;        /* 1 for '\0', 4 packetheader */
  2236.       if ((size % 4) != 0)
  2237.      size += (4 - (size % 4));
  2238.       mesPacket.pad1 = (char) size;
  2239.       sizes[CP_S_MESSAGE] = size;
  2240.       mesPacket.type = CP_S_MESSAGE;
  2241.    } else
  2242. #endif
  2243.       mesPacket.type = CP_MESSAGE;
  2244.    mesPacket.group = group;
  2245.    mesPacket.indiv = indiv;
  2246.    strncpy(mesPacket.mesg, mes, 80);
  2247. /*   printf("%s, %d, %d\n",mes,group,indiv);*/
  2248.    sendServerPacket((struct player_spacket *) & mesPacket);
  2249. }
  2250.  
  2251. #ifdef SHORT_PACKETS
  2252. sendThreshold(v)
  2253.     unsigned short  v;
  2254. {
  2255.    struct threshold_cpacket p;
  2256.  
  2257.    p.type = CP_S_THRS;
  2258.    p.thresh = v;
  2259.    sendServerPacket((struct player_spacket *) & p);
  2260. }
  2261. #endif
  2262.  
  2263. handleMask(packet)
  2264.     struct mask_spacket *packet;
  2265. {
  2266.    tournMask = packet->mask;
  2267. }
  2268.  
  2269. sendOptionsPacket()
  2270. {
  2271.    struct options_cpacket optPacket;
  2272.  
  2273.    optPacket.type = CP_OPTIONS;
  2274.    optPacket.flags =
  2275.       htonl(ST_MAPMODE * (mapmode != 0) +
  2276.         ST_NAMEMODE * namemode +
  2277.         ST_SHOWSHIELDS * showShields +
  2278.         ST_KEEPPEACE * keeppeace +
  2279.         ST_SHOWLOCAL * showlocal +
  2280.         ST_SHOWGLOBAL * showgalactic);
  2281.  
  2282. /* just in case - jn - hope all servers can deal with 0 */
  2283.   MZERO (optPacket.keymap, 96);
  2284.  
  2285.    sendServerPacket((struct player_spacket *) & optPacket);
  2286. }
  2287.  
  2288. pickSocket(old)
  2289.     int             old;
  2290. {
  2291.    int             newsocket;
  2292.    struct socket_cpacket sockPack;
  2293.    newsocket = (getpid() & 32767);
  2294.    while (newsocket < 2048 || newsocket == old) {
  2295.       newsocket = (newsocket + 10687) & 32767;
  2296.    }
  2297.    sockPack.type = CP_SOCKET;
  2298.    sockPack.socket = htonl(newsocket);
  2299.    sockPack.version = (char) SOCKVERSION;
  2300.    sockPack.udp_version = (char) UDPVERSION;
  2301.    sendServerPacket((struct player_spacket *) & sockPack);
  2302.    /* Did we get new socket # sent? */
  2303.    if (serverDead)
  2304.       return;
  2305.    nextSocket = newsocket;
  2306. }
  2307.  
  2308. handleBadVersion(packet)
  2309.     struct badversion_spacket *packet;
  2310. {
  2311.    switch (packet->why) {
  2312.    case 0:
  2313.       printf("Sorry, this is an invalid client version.\n");
  2314.       printf("You need a new version of the client code.\n");
  2315.       break;
  2316.    case 1:
  2317.    case 2:
  2318.    case 3:
  2319.    case 4:
  2320.    case 5:
  2321.    case 6:
  2322.       printf("Sorry, but you cannot play xtrek now.\n");
  2323.       printf("Try again later.\n");
  2324.       break;
  2325.    default:
  2326.       printf("Unknown message from handleBadVersion.\n");
  2327.       return;
  2328.    }
  2329.    exit(1);
  2330. }
  2331.  
  2332. gwrite(fd, buf, bytes)
  2333.     int             fd;
  2334.     char           *buf;
  2335.     register int    bytes;
  2336. {
  2337.    LONG            orig = bytes;
  2338.    register LONG   n;
  2339.    while (bytes) {
  2340.       n = write(fd, buf, bytes);
  2341.       if (n < 0) {
  2342.      if (fd == udpSock) {
  2343.         fprintf(stderr, "Tried to write %d, 0x%x, %d\n",
  2344.             fd, buf, bytes);
  2345.         perror("write");
  2346.         printUdpInfo();
  2347.      }
  2348.      return (-1);
  2349.       }
  2350.       bytes -= n;
  2351.       buf += n;
  2352.    }
  2353.    return (orig);
  2354. }
  2355.  
  2356. handleHostile(packet)
  2357.     struct hostile_spacket *packet;
  2358. {
  2359.    register struct player *pl;
  2360.  
  2361. #ifdef CORRUPTED_PACKETS
  2362.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2363.       fprintf(stderr, "handleHostile: bad index %d\n", packet->pnum);
  2364.       return;
  2365.    }
  2366. #endif
  2367.  
  2368.    pl = &players[packet->pnum];
  2369.    if (pl->p_swar != packet->war ||
  2370.        pl->p_hostile != packet->hostile) {
  2371.       /* FAT: prevent redundant player update & redraw */
  2372.       pl->p_swar = packet->war;
  2373.       pl->p_hostile = packet->hostile;
  2374.       updatePlayer[packet->pnum] = 1;
  2375.       redrawPlayer[packet->pnum] = 1;
  2376.    }
  2377. }
  2378.  
  2379. handlePlyrLogin(packet
  2380. #ifdef CORRUPTED_PACKETS
  2381.         ,sock
  2382. #endif
  2383. )
  2384.     struct plyr_login_spacket *packet;
  2385. {
  2386.    register struct player *pl;
  2387.  
  2388. #ifdef CORRUPTED_PACKETS
  2389.    if (sock == udpSock) {
  2390.       fprintf(stderr, "garbage packet discarded.\n");
  2391.       return;
  2392.    }
  2393. #endif
  2394.  
  2395. #ifdef CORRUPTED_PACKETS
  2396.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2397.       fprintf(stderr, "handlePlyrLogin: bad index %d\n", packet->pnum);
  2398.       return;
  2399.    }
  2400.    if (packet->rank < 0 || packet->rank >= NUMRANKS) {
  2401.       fprintf(stderr, "handlePlyrLogin: bad rank %d\n", packet->rank);
  2402.       return;
  2403.    }
  2404.    packet->name[sizeof(packet->name) - 1] = '\0';
  2405.    packet->monitor[sizeof(packet->monitor) - 1] = '\0';
  2406.    packet->login[sizeof(packet->login) - 1] = '\0';
  2407. #endif
  2408.    updatePlayer[packet->pnum] = 1;
  2409.  
  2410.    pl = &players[packet->pnum];
  2411.  
  2412.    strcpy(pl->p_name, packet->name);
  2413.    strcpyp_return(pl->p_monitor, packet->monitor, sizeof(pl->p_monitor));
  2414.    strcpy(pl->p_login, packet->login);
  2415.    pl->p_stats.st_rank = packet->rank;
  2416.  
  2417.    /*
  2418.     * printf("read player login %s, %s, %s\n", pl->p_name, pl->p_monitor,
  2419.     * pl->p_login);
  2420.     */
  2421.  
  2422.    if (packet->pnum == me->p_no) {
  2423.       /* This is me.  Set some stats */
  2424.       if (lastRank == -1) {
  2425.      if (loggedIn) {
  2426.         lastRank = packet->rank;
  2427.      }
  2428.       } else {
  2429.      if (lastRank != packet->rank) {
  2430.         lastRank = packet->rank;
  2431.         promoted = 1;
  2432.      }
  2433.       }
  2434.    }
  2435. }
  2436.  
  2437. handleStats(packet)
  2438.     struct stats_spacket *packet;
  2439. {
  2440.    register struct player *pl;
  2441.  
  2442. #ifdef CORRUPTED_PACKETS
  2443.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER)
  2444.    {
  2445.       fprintf(stderr, "handleStats: bad index %d\n", packet->pnum);
  2446.       return;
  2447.    }
  2448. #endif
  2449.  
  2450.    pl = &players[packet->pnum];
  2451.  
  2452. #ifdef NEW_PL
  2453.    /* only update if p_kills change since that's the only stat we
  2454.       show */
  2455.    if(!newPlist)
  2456. #endif
  2457.      updatePlayer[packet->pnum] = 1;
  2458.  
  2459.    pl->p_stats.st_tkills = ntohl(packet->tkills);
  2460.    pl->p_stats.st_tlosses = ntohl(packet->tlosses);
  2461.    pl->p_stats.st_kills = ntohl(packet->kills);
  2462.    pl->p_stats.st_losses = ntohl(packet->losses);
  2463.    pl->p_stats.st_tticks = ntohl(packet->tticks);
  2464.    pl->p_stats.st_tplanets = ntohl(packet->tplanets);
  2465.    pl->p_stats.st_tarmsbomb = ntohl(packet->tarmies);
  2466.    pl->p_stats.st_sbkills = ntohl(packet->sbkills);
  2467.    pl->p_stats.st_sblosses = ntohl(packet->sblosses);
  2468.    pl->p_stats.st_armsbomb = ntohl(packet->armies);
  2469.    pl->p_stats.st_planets = ntohl(packet->planets);
  2470. #ifdef SBHOURS
  2471.   if ((pl->p_ship.s_type == STARBASE) && (SBhours))
  2472.   {
  2473.    pl->p_stats.st_sbticks = ntohl (packet->maxkills);
  2474.   }
  2475.   else
  2476.   {
  2477.    pl->p_stats.st_maxkills = ntohl (packet->maxkills) / 100.0;
  2478.   } 
  2479. #else
  2480.    pl->p_stats.st_maxkills = ntohl(packet->maxkills) / 100.0;
  2481. #endif
  2482.    pl->p_stats.st_sbmaxkills = ntohl(packet->sbmaxkills) / 100.0;
  2483. }
  2484.  
  2485. handlePlyrInfo(packet)
  2486.     struct plyr_info_spacket *packet;
  2487. {
  2488.    register struct player *pl;
  2489.    static int      lastship = -1;
  2490.  
  2491. #ifdef CORRUPTED_PACKETS
  2492.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2493.       fprintf(stderr, "handlePlyrInfo: bad index %d\n", packet->pnum);
  2494.       return;
  2495.    }
  2496.    if (packet->team < 0 || packet->team > ALLTEAM) {
  2497.       fprintf(stderr, "handlePlyrInfo: bad team %d\n", packet->team);
  2498.       return;
  2499.    }
  2500. #endif
  2501.  
  2502.    updatePlayer[packet->pnum] = 1;
  2503.    pl = &players[packet->pnum];
  2504.    getship(&pl->p_ship, packet->shiptype);
  2505.    pl->p_team = packet->team;
  2506.  
  2507.    pl->p_mapchars[0] = teamlet[pl->p_team];
  2508.    pl->p_mapchars[1] = shipnos[pl->p_no];
  2509.    if (me == pl && lastship != me->p_ship.s_type) {
  2510.       redrawTstats();
  2511.       calibrate_stats();
  2512.       redrawStats();        /* TSH */
  2513.    }
  2514.    redrawPlayer[packet->pnum] = 1;
  2515. }
  2516.  
  2517. sendUpdatePacket(speed)
  2518.     LONG            speed;
  2519. {
  2520.    struct updates_cpacket packet;
  2521.  
  2522.    packet.type = CP_UPDATES;
  2523.    timerDelay = speed;
  2524.    packet.usecs = htonl(speed);
  2525.    sendServerPacket((struct player_spacket *) & packet);
  2526. }
  2527.  
  2528. handlePlanetLoc(packet)
  2529.     struct planet_loc_spacket *packet;
  2530. {
  2531.    struct planet  *pl;
  2532.  
  2533. #ifdef CORRUPTED_PACKETS
  2534.    if (packet->pnum < 0 || packet->pnum >= MAXPLANETS) {
  2535.       fprintf(stderr, "handlePlanetLoc: bad index\n");
  2536.       return;
  2537.    }
  2538. #endif
  2539.  
  2540.    pl = &planets[packet->pnum];
  2541.    pl_update[packet->pnum].plu_x = pl->pl_x;
  2542.    pl_update[packet->pnum].plu_y = pl->pl_y;
  2543.  
  2544.    if (pl_update[packet->pnum].plu_update != -1) {
  2545.       pl_update[packet->pnum].plu_update = 1;
  2546.       /*
  2547.        * printf("update: %s, old (%d,%d) new (%d,%d)\n", pl->pl_name,
  2548.        * pl->pl_x, pl->pl_y, ntohl(packet->x),ntohl(packet->y));
  2549.        */
  2550.    } else
  2551.       pl_update[packet->pnum].plu_update = 0;
  2552.  
  2553.    pl->pl_x = ntohl(packet->x);
  2554.    pl->pl_y = ntohl(packet->y);
  2555.    strcpy(pl->pl_name, packet->name);
  2556.    pl->pl_namelen = strlen(packet->name);
  2557.    pl->pl_flags |= (PLREDRAW|PLCLEAR);
  2558.    reinitPlanets = 1;
  2559.  
  2560. #ifdef ROTATERACE
  2561.    if (rotate) {
  2562.       rotate_coord(&pl->pl_x, &pl->pl_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
  2563.    }
  2564. #endif
  2565. }
  2566.  
  2567.  
  2568. handleReserved(packet
  2569. #ifdef CORRUPTED_PACKETS
  2570.            ,sock
  2571. #endif
  2572. )
  2573.     struct reserved_spacket *packet;
  2574. {
  2575.    struct reserved_cpacket response;
  2576.  
  2577. #ifdef CORRUPTED_PACKETS
  2578.    if (sock == udpSock) {
  2579.       fprintf(stderr, "garbage Reserved packet discarded.\n");
  2580.       return;
  2581.    }
  2582. #endif
  2583.  
  2584. #ifdef FOR_MORONS
  2585.    {                /* it _is_ an 'info' borg, after all.  ;-) */
  2586.       extern int      For_Morons;
  2587.       if (For_Morons)
  2588.      return;
  2589.    }
  2590. #endif
  2591.  
  2592. #if !defined(BORG)
  2593. #ifndef RSA
  2594.    encryptReservedPacket(packet, &response, serverName, me->p_no);
  2595.    sendServerPacket((struct player_spacket *) & response);
  2596. #else
  2597.  
  2598.    if (RSA_Client) {        /* can use -o option for old blessing */
  2599.       /* client sends back a 'reserved' packet just saying RSA_VERSION info */
  2600.       /*
  2601.        * theoretically, the server then sends off a rsa_key_spacket * for the
  2602.        * client to then respond to
  2603.        */
  2604.       warning(RSA_VERSION);
  2605.       strncpy(response.resp, RSA_VERSION, RESERVED_SIZE);
  2606.       bcopy(packet->data, response.data, RESERVED_SIZE);
  2607.       response.type = CP_RESERVED;
  2608. #ifdef DEBUG
  2609.       printf("Sending RSA reserved response\n");
  2610. #endif
  2611.    } else{
  2612. #ifdef FEATURE
  2613.       /* If server gods don't like NEWMACRO/SMARTMACRO
  2614.      they better install RSA... */
  2615.       F_UseNewMacro = 1;
  2616.       F_UseSmartMacro = 1;
  2617. #endif
  2618.       encryptReservedPacket(packet, &response, serverName, me->p_no);
  2619.    }
  2620.  
  2621.    sendServerPacket(&response);
  2622.  
  2623. #endif                /* RSA */
  2624. #endif                /* defined(BORG) */
  2625. }
  2626.  
  2627. #ifdef RSA
  2628. handleRSAKey(packet)
  2629.     struct rsa_key_spacket *packet;
  2630. {
  2631.    struct rsa_key_cpacket response;
  2632.    struct sockaddr_in saddr;
  2633.    u_short port;
  2634.    unsigned char* data;
  2635.    int len;
  2636.    struct timeval start, end;
  2637. #ifdef GATEWAY
  2638.    extern unsigned LONG netaddr;
  2639.    extern int serv_port;
  2640. #endif
  2641.  
  2642. #ifdef GATEWAY
  2643.    /* if we didn't get it from -H, go ahead and query the socket */
  2644.    if (netaddr == 0) {
  2645.        len = sizeof(saddr);
  2646.        if (getpeername(sock,(struct sockaddr*)&saddr, &len) < 0) {
  2647.            perror("getpeername(sock)");
  2648.            exit(1);
  2649.        }
  2650.    } else {
  2651.        saddr.sin_addr.s_addr = netaddr;
  2652.        saddr.sin_port = htons(serv_port);
  2653.    }
  2654. #else
  2655.            /* query the socket to determine the remote host (ATM) */
  2656.     len = sizeof(saddr);
  2657.     if (getpeername(sock,(struct sockaddr*) &saddr, &len) < 0) {
  2658.         perror("getpeername(sock)");
  2659.         exit(1);
  2660.     }
  2661. #endif
  2662.  
  2663.    data = packet->data;
  2664.    bcopy(&saddr.sin_addr.s_addr, data, sizeof(saddr.sin_addr.s_addr));
  2665.    data += sizeof(saddr.sin_addr.s_addr);
  2666.    bcopy(&saddr.sin_port, data, sizeof(saddr.sin_port));
  2667.  
  2668.    gettimeofday(&start, NULL);
  2669.    rsa_black_box(response.resp, packet->data,
  2670.                  response.public, response.global);
  2671.    gettimeofday(&end, NULL);
  2672.    printf("rsa_black_box took %d ms.\n",
  2673.           (1000 * (end.tv_sec - start.tv_sec) +
  2674.            (end.tv_usec - start.tv_usec) / 1000));
  2675.  
  2676.    response.type = CP_RSA_KEY;
  2677.  
  2678. #ifdef FEATURE
  2679.   if (report_features)
  2680.     reportFeatures ();
  2681. #endif
  2682.  
  2683.    sendServerPacket(&response);
  2684. /* #ifdef DEBUG */
  2685.    printf("RSA verification requested.\n");
  2686. /* #endif */
  2687. }
  2688. #endif
  2689.  
  2690. #ifdef INCLUDE_SCAN
  2691. handleScan(packet)
  2692.     struct scan_spacket *packet;
  2693. {
  2694.    struct player  *pp;
  2695. #ifdef CORRUPTED_PACKETS
  2696.    if (packet->pnum < 0 || packet->pnum >= MAXPLAYER) {
  2697.       fprintf(stderr, "handleScan: bad index\n");
  2698.       return;
  2699.    }
  2700. #endif
  2701.  
  2702.    if (packet->success) {
  2703.       pp = &players[packet->pnum];
  2704.       pp->p_fuel = ntohl(packet->p_fuel);
  2705.       pp->p_armies = ntohl(packet->p_armies);
  2706.       pp->p_shield = ntohl(packet->p_shield);
  2707.       pp->p_damage = ntohl(packet->p_damage);
  2708.       pp->p_etemp = ntohl(packet->p_etemp);
  2709.       pp->p_wtemp = ntohl(packet->p_wtemp);
  2710.       informScan(packet->pnum);
  2711.    }
  2712. }
  2713.  
  2714. informScan(p)
  2715.     int             p;
  2716. {
  2717. }
  2718.  
  2719. #endif                /* INCLUDE_SCAN */
  2720.  
  2721. /*
  2722.  * UDP stuff
  2723.  */
  2724. sendUdpReq(req)
  2725.     int             req;
  2726. {
  2727.    struct udp_req_cpacket packet;
  2728.  
  2729.    packet.type = CP_UDP_REQ;
  2730.    packet.request = req;
  2731.  
  2732.    if (req >= COMM_MODE) {
  2733.       packet.request = COMM_MODE;
  2734.       packet.connmode = req - COMM_MODE;
  2735.       sendServerPacket(&packet);
  2736.       return;
  2737.    }
  2738.    if (req == COMM_UPDATE) {
  2739. #ifdef SHORT_PACKETS
  2740.       if (recv_short) {        /* not necessary */
  2741.      /* Let the client do the work, and not the network :-) */
  2742.      register int    i;
  2743.      for (i = 0; i < MAXPLAYER * MAXTORP; i++)
  2744.         torps[i].t_status = TFREE;
  2745.  
  2746.      for (i = 0; i < MAXPLAYER * MAXPLASMA; i++)
  2747.         plasmatorps[i].pt_status = PTFREE;
  2748.  
  2749.      for (i = 0; i < MAXPLAYER; i++) {
  2750.         players[i].p_ntorp = 0;
  2751.         players[i].p_nplasmatorp = 0;
  2752.         phasers[i].ph_status = PHFREE;
  2753.      }
  2754.       }
  2755. #endif
  2756.       sendServerPacket(&packet);
  2757.       warning("Sent request for full update");
  2758.       return;
  2759.    }
  2760.    if (req == commModeReq) {
  2761.       warning("Request is in progress, do not disturb");
  2762.       return;
  2763.    }
  2764.    if (req == COMM_UDP) {
  2765.       /* open UDP port */
  2766.       if (openUdpConn() >= 0) {
  2767.      UDPDIAG(("Bound to local port %d on fd %d\n", udpLocalPort, udpSock));
  2768.       } else {
  2769.      UDPDIAG(("Bind to local port %d failed\n", udpLocalPort));
  2770.      commModeReq = COMM_TCP;
  2771.      commStatus = STAT_CONNECTED;
  2772.      commSwitchTimeout = 0;
  2773.      if (udpWin)
  2774.         udprefresh(UDP_STATUS);
  2775.      warning("Unable to establish UDP connection");
  2776.  
  2777.      return;
  2778.       }
  2779.    }
  2780.    /* send the request */
  2781.    packet.type = CP_UDP_REQ;
  2782.    packet.request = req;
  2783.    packet.port = htonl(udpLocalPort);
  2784. #ifdef GATEWAY
  2785.    if (!strcmp(serverName, gw_mach)) {
  2786.       packet.port = htons(gw_serv_port);    /* gw port that server should
  2787.                          * call */
  2788.       UDPDIAG(("+ Telling server to contact us on %d\n", gw_serv_port));
  2789.    }
  2790. #endif
  2791. #ifdef USE_PORTSWAP
  2792.    packet.connmode = CONNMODE_PORT;    /* have him send his port */
  2793. #else
  2794.    packet.connmode = CONNMODE_PACKET;    /* we get addr from packet */
  2795. #endif
  2796.    sendServerPacket((struct player_spacket *) & packet);
  2797.  
  2798.    /* update internal state stuff */
  2799.    commModeReq = req;
  2800.    if (req == COMM_TCP)
  2801.       commStatus = STAT_SWITCH_TCP;
  2802.    else
  2803.       commStatus = STAT_SWITCH_UDP;
  2804.    commSwitchTimeout = 25;    /* wait 25 updates (about five seconds) */
  2805.  
  2806.    UDPDIAG(("Sent request for %s mode\n", (req == COMM_TCP) ?
  2807.         "TCP" : "UDP"));
  2808.  
  2809. #ifndef USE_PORTSWAP
  2810.    if ((req == COMM_UDP) && recvUdpConn() < 0) {
  2811.       UDPDIAG(("Sending TCP reset message\n"));
  2812.       packet.request = COMM_TCP;
  2813.       packet.port = 0;
  2814.       commModeReq = COMM_TCP;
  2815.       sendServerPacket((struct player_spacket *) & packet);
  2816.       /* we will likely get a SWITCH_UDP_OK later; better ignore it */
  2817.       commModeReq = COMM_TCP;
  2818.       commStatus = STAT_CONNECTED;
  2819.       commSwitchTimeout = 0;
  2820.    }
  2821. #endif
  2822.  
  2823.    if (udpWin)
  2824.       udprefresh(UDP_STATUS);
  2825. }
  2826. handleUdpReply(packet)
  2827.     struct udp_reply_spacket *packet;
  2828. {
  2829.    struct udp_req_cpacket response;
  2830.  
  2831.    UDPDIAG(("Received UDP reply %d\n", packet->reply));
  2832.    commSwitchTimeout = 0;
  2833.  
  2834.    response.type = CP_UDP_REQ;
  2835.  
  2836.    switch (packet->reply) {
  2837.    case SWITCH_TCP_OK:
  2838.       if (commMode == COMM_TCP) {
  2839.      UDPDIAG(("Got SWITCH_TCP_OK while in TCP mode; ignoring\n"));
  2840.       } else {
  2841.      commMode = COMM_TCP;
  2842.      commStatus = STAT_CONNECTED;
  2843.      warning("Switched to TCP-only connection");
  2844.      closeUdpConn();
  2845.      UDPDIAG(("UDP port closed\n"));
  2846.      if (udpWin) {
  2847.         udprefresh(UDP_STATUS);
  2848.         udprefresh(UDP_CURRENT);
  2849.      }
  2850.       }
  2851.       break;
  2852.    case SWITCH_UDP_OK:
  2853.       if (commMode == COMM_UDP) {
  2854.      UDPDIAG(("Got SWITCH_UDP_OK while in UDP mode; ignoring\n"));
  2855.       } else {
  2856.      /* the server is forcing UDP down our throat? */
  2857.      if (commModeReq != COMM_UDP) {
  2858.         UDPDIAG(("Got unsolicited SWITCH_UDP_OK; ignoring\n"));
  2859.      } else {
  2860. #ifdef USE_PORTSWAP
  2861.         udpServerPort = ntohl(packet->port);
  2862.         if (connUdpConn() < 0) {
  2863.            UDPDIAG(("Unable to connect, resetting\n"));
  2864.            warning("Connection attempt failed");
  2865.            commModeReq = COMM_TCP;
  2866.            commStatus = STAT_CONNECTED;
  2867.            if (udpSock >= 0)
  2868.           closeUdpConn();
  2869.            if (udpWin) {
  2870.           udprefresh(UDP_STATUS);
  2871.           udprefresh(UDP_CURRENT);
  2872.            }
  2873.            response.request = COMM_TCP;
  2874.            response.port = 0;
  2875.            goto send;
  2876.         }
  2877. #else
  2878.         /* this came down UDP, so we MUST be connected */
  2879.         /* (do the verify thing anyway just for kicks) */
  2880. #endif
  2881.         UDPDIAG(("Connected to server's UDP port\n"));
  2882.         commStatus = STAT_VERIFY_UDP;
  2883.         if (udpWin)
  2884.            udprefresh(UDP_STATUS);
  2885.         response.request = COMM_VERIFY;    /* send verify request on UDP */
  2886.         response.port = 0;
  2887.         commSwitchTimeout = 25;    /* wait 25 updates */
  2888.       send:
  2889.         sendServerPacket((struct player_spacket *) & response);
  2890.      }
  2891.       }
  2892.       break;
  2893.    case SWITCH_DENIED:
  2894.       if (ntohs(packet->port)) {
  2895.      UDPDIAG(("Switch to UDP failed (different version)\n"));
  2896.      warning("UDP protocol request failed (bad version)");
  2897.       } else {
  2898.      UDPDIAG(("Switch to UDP denied\n"));
  2899.      warning("UDP protocol request denied");
  2900.       }
  2901.       commModeReq = commMode;
  2902.       commStatus = STAT_CONNECTED;
  2903.       commSwitchTimeout = 0;
  2904.       if (udpWin)
  2905.      udprefresh(UDP_STATUS);
  2906.       if (udpSock >= 0)
  2907.      closeUdpConn();
  2908.       break;
  2909.    case SWITCH_VERIFY:
  2910.       UDPDIAG(("Received UDP verification\n"));
  2911.       break;
  2912.    default:
  2913.       fprintf(stderr, "netrek: Got funny reply (%d) in UDP_REPLY packet\n",
  2914.           packet->reply);
  2915.       break;
  2916.    }
  2917. }
  2918.  
  2919. #define MAX_PORT_RETRY  10
  2920. openUdpConn()
  2921. {
  2922.    struct sockaddr_in addr;
  2923.    struct hostent *hp;
  2924.    int             attempts;
  2925.  
  2926.    if (udpSock >= 0) {
  2927.       fprintf(stderr, "netrek: tried to open udpSock twice\n");
  2928.       return (0);        /* pretend we succeeded (this could be bad) */
  2929.    }
  2930.    if ((udpSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  2931.       perror("netrek: unable to create DGRAM socket");
  2932.       return (-1);
  2933.    }
  2934. #ifdef nodef
  2935.    set_udp_opts(udpSock);
  2936. #endif                /* nodef */
  2937.  
  2938.    if(udpSock >= max_fd)
  2939.       max_fd = udpSock+1;
  2940.  
  2941.    addr.sin_addr.s_addr = INADDR_ANY;
  2942.    addr.sin_family = AF_INET;
  2943.  
  2944.    errno = 0;
  2945.  
  2946. #ifdef USE_TR_PORTS
  2947.    if (useTRPorts)
  2948.      udpLocalPort = 33400;
  2949.    else
  2950.      udpLocalPort = (getpid() & 32767) + (random() % 256);
  2951. #else
  2952.    udpLocalPort = (getpid() & 32767) + (random() % 256);
  2953. #endif
  2954.      
  2955.    for (attempts = 0; attempts < MAX_PORT_RETRY; attempts++) {
  2956.       while (udpLocalPort < 2048) {
  2957.      udpLocalPort = (udpLocalPort + 10687) & 32767;
  2958.       }
  2959. #ifdef GATEWAY
  2960.       /* we need the gateway to know where to find us */
  2961.       if (!strcmp(serverName, gw_mach)) {
  2962.      UDPDIAG(("+ gateway test: binding to %d\n", gw_local_port));
  2963.      udpLocalPort = gw_local_port;
  2964.       }
  2965. #endif
  2966.       addr.sin_port = htons(udpLocalPort);
  2967.       if (bind(udpSock, &addr, sizeof(addr)) >= 0)
  2968.      break;
  2969.    }
  2970.    if (attempts == MAX_PORT_RETRY) {
  2971.       perror("netrek: bind");
  2972.       UDPDIAG(("Unable to find a local port to bind to\n"));
  2973.       close(udpSock);
  2974.       udpSock = -1;
  2975.       return (-1);
  2976.    }
  2977.    UDPDIAG(("Local port is %d\n", udpLocalPort));
  2978.  
  2979.    /* determine the address of the server */
  2980.    if (!serveraddr) {
  2981.       if ((addr.sin_addr.s_addr = inet_addr(serverName)) == -1) {
  2982.      if ((hp = gethostbyname(serverName)) == NULL) {
  2983.         printf("Who is %s?\n", serverName);
  2984.         exit(0);
  2985.      } else {
  2986.         addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
  2987.      }
  2988.       }
  2989.       serveraddr = addr.sin_addr.s_addr;
  2990.       UDPDIAG(("Found serveraddr == 0x%x\n", serveraddr));
  2991.    }
  2992.    return (0);
  2993. }
  2994.  
  2995. #ifdef USE_PORTSWAP
  2996. connUdpConn()
  2997. {
  2998.    struct sockaddr_in addr;
  2999.    int             len;
  3000.  
  3001.    addr.sin_addr.s_addr = serveraddr;
  3002.    addr.sin_family = AF_INET;
  3003.    addr.sin_port = htons(udpServerPort);
  3004.  
  3005.    UDPDIAG(("Connecting to host 0x%x on port %d\n", serveraddr, udpServerPort));
  3006.    if (connect(udpSock, &addr, sizeof(addr)) < 0) {
  3007.       fprintf(stderr, "Error %d: ");
  3008.       perror("netrek: unable to connect UDP socket");
  3009.       printUdpInfo();        /* debug */
  3010.       return (-1);
  3011.    }
  3012. #ifdef nodef
  3013.    len = sizeof(addr);
  3014.    if (getsockname(udpSock, &addr, &len) < 0) {
  3015.       perror("netrek: unable to getsockname(UDP)");
  3016.       UDPDIAG(("Can't get our own socket; connection failed\n"));
  3017.       close(udpSock);
  3018.       udpSock = -1;
  3019.       return -1;
  3020.    }
  3021.    printf("udpLocalPort %d, getsockname port %d\n",
  3022.       udpLocalPort, addr.sin_port);
  3023. #endif
  3024.  
  3025.    return (0);
  3026. }
  3027. #endif
  3028.  
  3029. #ifndef USE_PORTSWAP
  3030. recvUdpConn()
  3031. {
  3032.    fd_set          readfds;
  3033.    struct timeval  to;
  3034.    struct sockaddr_in from;
  3035.    struct sockaddr_in addr;
  3036.    int             fromlen, res;
  3037.    int            i;
  3038.  
  3039.    bzero(&from, sizeof(from));    /* don't get garbage if really broken */
  3040.  
  3041.    ns_init(3);
  3042.  
  3043.    /* we patiently wait until the server sends a packet to us */
  3044.    /* (note that we silently eat the first one) */
  3045.    UDPDIAG(("Issuing recvfrom() call\n"));
  3046.    printUdpInfo();
  3047.    fromlen = sizeof(from);
  3048. tryagain:
  3049.    FD_ZERO(&readfds);
  3050.    FD_SET(udpSock, &readfds);
  3051.    to.tv_sec = 6;        /* wait 3 seconds, then abort */
  3052.    to.tv_usec = 0;
  3053.    if ((res = select(max_fd, &readfds, 0, 0, &to)) <= 0) {
  3054.       if (!res) {
  3055.      UDPDIAG(("timed out waiting for response"));
  3056.      warning("UDP connection request timed out");
  3057.      return (-1);
  3058.       } else {
  3059.      perror("select() before recvfrom()");
  3060.      return (-1);
  3061.       }
  3062.    }
  3063.    if (recvfrom(udpSock, buf, BUFSIZE, 0, &from, &fromlen) < 0) {
  3064.       perror("recvfrom");
  3065.       UDPDIAG(("recvfrom failed, aborting UDP attempt"));
  3066.       return (-1);
  3067.    }
  3068.    if (from.sin_addr.s_addr != serveraddr) {
  3069.       /* safe? */
  3070.       serveraddr = from.sin_addr.s_addr;
  3071.       UDPDIAG(("Warning: from 0x%x, but server is 0x%x\n",
  3072.            from.sin_addr.s_addr, serveraddr));
  3073.    }
  3074.    if (from.sin_family != AF_INET) {
  3075.       UDPDIAG(("Warning: not AF_INET (%d)\n", from.sin_family));
  3076.    }
  3077.    udpServerPort = ntohs(from.sin_port);
  3078.    UDPDIAG(("recvfrom() succeeded; will use server port %d\n", udpServerPort));
  3079. #ifdef GATEWAY
  3080.    if (!strcmp(serverName, gw_mach)) {
  3081.       UDPDIAG(("+ actually, I'm going to use %d\n", gw_port));
  3082.       udpServerPort = gw_port;
  3083.       from.sin_port = htons(udpServerPort);
  3084.    }
  3085. #endif
  3086.  
  3087.    if (connect(udpSock, &from, sizeof(from)) < 0) {
  3088.       perror("netrek: unable to connect UDP socket after recvfrom()");
  3089.       close(udpSock);
  3090.       udpSock = -1;
  3091.       return (-1);
  3092.    }
  3093.    return (0);
  3094. }
  3095. #endif
  3096.  
  3097. closeUdpConn()
  3098. {
  3099.    V_UDPDIAG(("Closing UDP socket\n"));
  3100.    if (udpSock < 0) {
  3101.       fprintf(stderr, "netrek: tried to close a closed UDP socket\n");
  3102.       return (-1);
  3103.    }
  3104.    shutdown(udpSock, 2);
  3105.    close(udpSock);
  3106.    udpSock = -1;
  3107.    return 0;
  3108. }
  3109.  
  3110. printUdpInfo()
  3111. {
  3112.    struct sockaddr_in addr;
  3113.    int             len;
  3114.  
  3115.    len = sizeof(addr);
  3116.    if (getsockname(udpSock, &addr, &len) < 0) {
  3117.       /* perror("printUdpInfo: getsockname"); */
  3118.       return;
  3119.    }
  3120.    UDPDIAG(("LOCAL: addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
  3121.         addr.sin_family, ntohs(addr.sin_port)));
  3122.  
  3123.    if (getpeername(udpSock, &addr, &len) < 0) {
  3124.       /* perror("printUdpInfo: getpeername"); */
  3125.       return;
  3126.    }
  3127.    UDPDIAG(("PEER : addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
  3128.         addr.sin_family, ntohs(addr.sin_port)));
  3129. }
  3130.  
  3131. handleSequence(packet)
  3132.     struct sequence_spacket *packet;
  3133. {
  3134.    static int      recent_count = 0, recent_dropped = 0;
  3135.    LONG            newseq;
  3136.  
  3137.    drop_flag = 0;
  3138.    if (chan != udpSock)
  3139.       return;            /* don't pay attention to TCP sequence #s */
  3140.    udpTotal++;
  3141.    recent_count++;
  3142.  
  3143.    /* update percent display every 256 updates (~50 seconds usually) */
  3144.    if (!(udpTotal & 0xff))
  3145.       if (udpWin)
  3146.      udprefresh(UDP_DROPPED);
  3147.  
  3148.    newseq = (LONG) ntohs(packet->sequence);
  3149.    /* printf("read %d - ", newseq); */
  3150.  
  3151.    if (((unsigned short) sequence) > 65000 &&
  3152.        ((unsigned short) newseq) < 1000) {
  3153.       /* we rolled, set newseq = 65536+sequence and accept it */
  3154.       sequence = ((sequence + 65536) & 0xffff0000) | newseq;
  3155.    } else {
  3156.       /* adjust newseq and do compare */
  3157.       newseq |= (sequence & 0xffff0000);
  3158.  
  3159.       if (!udpSequenceChk) {    /* put this here so that turning seq check */
  3160.      sequence = newseq;    /* on and off doesn't make us think we lost */
  3161.      return;        /* a whole bunch of packets. */
  3162.       }
  3163.       if (newseq > sequence) {
  3164.      /* accept */
  3165.      if (newseq != sequence + 1) {
  3166.         udpDropped += (newseq - sequence) - 1;
  3167.         udpTotal += (newseq - sequence) - 1;    /* want TOTAL packets */
  3168.         recent_dropped += (newseq - sequence) - 1;
  3169.         recent_count += (newseq - sequence) - 1;
  3170.         if (udpWin)
  3171.            udprefresh(UDP_DROPPED);
  3172.         UDPDIAG(("sequence=%d, newseq=%d, we lost some\n",
  3173.              sequence, newseq));
  3174.      }
  3175.      sequence = newseq;
  3176.       } else {
  3177.      /* reject */
  3178.      if (packet->type == SP_SC_SEQUENCE) {
  3179.         V_UDPDIAG(("(ignoring repeat %d)\n", newseq));
  3180.      } else {
  3181.         UDPDIAG(("sequence=%d, newseq=%d, ignoring transmission\n",
  3182.              sequence, newseq));
  3183.      }
  3184. #ifdef PING
  3185.      /*
  3186.       * the remaining packets will be dropped and we shouldn't count the
  3187.       * SP_SEQUENCE packet either
  3188.       */
  3189.      packets_received--;
  3190. #endif
  3191.      drop_flag = 1;
  3192.       }
  3193.    }
  3194.    /* printf("newseq %d, sequence %d\n", newseq, sequence); */
  3195.    if (recent_count > UDP_RECENT_INTR) {
  3196.       /* once a minute (at 5 upd/sec), report on how many were dropped */
  3197.       /* during the last UDP_RECENT_INTR updates                       */
  3198.       udpRecentDropped = recent_dropped;
  3199.       recent_count = recent_dropped = 0;
  3200.       if (udpWin)
  3201.      udprefresh(UDP_DROPPED);
  3202.    }
  3203. }
  3204.  
  3205. #ifdef SHORT_PACKETS
  3206. handleShortReply(packet)
  3207.     struct shortreply_spacket *packet;
  3208. {
  3209.    switch (packet->repl) {
  3210.    case SPK_VOFF:
  3211.       recv_short = recv_short_opt = 0;
  3212.       optionredrawoption(&recv_short_opt);
  3213.       break;
  3214.    case SPK_VON:
  3215.       recv_short = recv_short_opt = 1;
  3216.       optionredrawoption(&recv_short_opt);
  3217.       spwinside = ntohs(packet->winside);
  3218.       spgwidth = ntohl(packet->gwidth);
  3219.       break;
  3220.  
  3221.    case SPK_THRESHOLD:
  3222.       break;
  3223.    default:
  3224.       fprintf(stderr, "%s: unknown response packet value short-req: %d\n",
  3225.           "netrek", packet->repl);
  3226.    }
  3227. }
  3228.  
  3229.  
  3230. handleVTorpInfo(sbuf)
  3231.     unsigned char  *sbuf;
  3232. {
  3233.    unsigned char  *bitset, *which, *data, *infobitset, *infodata;
  3234.    struct torp    *thetorp;
  3235.    int             dx, dy;
  3236.    int             shiftvar;
  3237.    char            status, war;
  3238.    register int    i;
  3239.    register int    shift = 0;    /* How many torps are extracted (for shifting
  3240.                  * ) */
  3241.  
  3242.    /* now we must find the data ... :-) */
  3243.    bitset = &sbuf[1];
  3244.    which = &sbuf[2];
  3245.    infobitset = &sbuf[3];
  3246.    /* Where is the data ? */
  3247.    data = &sbuf[4];
  3248.    infodata = &sbuf[vtisize[numofbits[(unsigned char) sbuf[1]]]];
  3249.  
  3250. #ifdef CORRUPTED_PACKETS
  3251.    /* we probably should do something clever here - jmn */
  3252.    if(*which * 8 >= MAXPLAYER * MAXTORP){
  3253.       fprintf(stderr, "handleVTorp: bad index %d\n", *which * 8);
  3254.       return;
  3255.    }
  3256. #endif
  3257.  
  3258.    thetorp = &torps[((unsigned char) *which * 8)];
  3259.  
  3260.    for (shift = 0, i = 0;    /* (unsigned char)*infobitset !=0 ||
  3261.        (unsigned char )*bitset != 0 */ i < 8;
  3262.     thetorp++, 
  3263.     *bitset >>= 1, 
  3264.     *infobitset >>= 1, 
  3265.     i++) {
  3266.  
  3267.       if (*bitset & 01) {
  3268.      dx = (*data >> shift);
  3269.      data++;
  3270.      shiftvar = (unsigned char) *data;    /* to silence gcc */
  3271.      shiftvar <<= (8 - shift);
  3272.      dx |= (shiftvar & 511);
  3273.      shift++;
  3274.      dy = (*data >> shift);
  3275.      data++;
  3276.      shiftvar = (unsigned char) *data;    /* to silence gcc */
  3277.      shiftvar <<= (8 - shift);
  3278.      dy |= (shiftvar & 511);
  3279.      shift++;
  3280.      if (shift == 8) {
  3281.         shift = 0;
  3282.         data++;
  3283.      }
  3284.      /*
  3285.       * Check for torp with no TorpInfo ( In case we missed a n
  3286.       * updateAll)
  3287.       */
  3288.      if (!(*infobitset & 01)) {
  3289.         if (thetorp->t_status == TFREE) {
  3290.            thetorp->t_status = TMOVE;    /* guess */
  3291.            players[thetorp->t_owner].p_ntorp++;
  3292.         }
  3293.         else if (thetorp->t_owner == me->p_no &&
  3294.              thetorp->t_status == TEXPLODE)
  3295.            thetorp->t_status = TMOVE;
  3296.      }
  3297.      /* Check if torp is visible */
  3298.      if (dx > SPWINSIDE || dy > SPWINSIDE) {
  3299.         thetorp->t_x = -100000;    /* Not visible */
  3300.         thetorp->t_y = -100000;
  3301.      } else {        /* visible */
  3302.         thetorp->t_x = my_x + ((dx - SPWINSIDE / 2) *
  3303.                       SCALE);
  3304.         thetorp->t_y = my_y + ((dy - SPWINSIDE / 2) *
  3305.                       SCALE);
  3306. #ifdef ROTATERACE
  3307.         if (rotate) {
  3308.            rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
  3309.            GWIDTH / 2, GWIDTH / 2);
  3310.         }
  3311. #endif
  3312.      }
  3313.       }
  3314.       /* if */ 
  3315.       else {            /* Got a TFREE ? */
  3316.      if (!(*infobitset & 01)) {    /* No other TorpInfo for this Torp */
  3317.                             /* tsh */
  3318.         if (thetorp->t_status && thetorp->t_status != TEXPLODE) {
  3319.            players[thetorp->t_owner].p_ntorp--;
  3320.            thetorp->t_status = TFREE;    /* That's no guess */
  3321.         }
  3322.      }
  3323.       }
  3324.       /* Now the TorpInfo */
  3325.       if (*infobitset & 01) {
  3326.      war = (unsigned char) *infodata & 15 /* 0x0f */ ;
  3327.      status = ((unsigned char) *infodata & 0xf0) >> 4;
  3328.      infodata++;
  3329.  
  3330.      /*
  3331.      if(status == TEXPLODE)
  3332.         printf("explode fuse set %d, status: %d, %d\n", thetorp->t_no, 
  3333.            thetorp->t_status, __LINE__);
  3334.  
  3335.      if(thetorp->t_status == TEXPLODE && status == TFREE)
  3336.         printf("we have a reset %d\n", __LINE__);
  3337.      */
  3338.  
  3339.      if (status == TEXPLODE && thetorp->t_status == TFREE) {
  3340.         /* FAT: redundant explosion; don't update p_ntorp */
  3341.         continue;
  3342.      }
  3343.      if (thetorp->t_status == TFREE && status) {
  3344.         players[thetorp->t_owner].p_ntorp++;
  3345.      }
  3346.      if (thetorp->t_status && status == TFREE) {
  3347.         players[thetorp->t_owner].p_ntorp--;
  3348.      }
  3349.      thetorp->t_war = war;
  3350.      if (status != thetorp->t_status) {
  3351.         /* FAT: prevent explosion reset */
  3352.         thetorp->t_status = status;
  3353.         if (thetorp->t_status == TEXPLODE) {
  3354.            thetorp->t_fuse = NUMDETFRAMES;
  3355.         }
  3356.         /*
  3357.         if (thetorp->t_status == TFREE)
  3358.            printf("torp freed %d, %d\n", thetorp->t_no, __LINE__);
  3359.         */
  3360.      }
  3361.       }                /* if */
  3362.    }                /* for */
  3363. }
  3364.  
  3365. handleVPlanet(sbuf)
  3366.     unsigned char  *sbuf;
  3367. {
  3368.    register int    i;
  3369.    register int    numofplanets;/* How many Planets are in the packet */
  3370.    struct planet  *plan;
  3371.    struct planet_s_spacket *packet = (struct planet_s_spacket *) & sbuf[2];
  3372.    /* FAT: prevent excessive redraw */
  3373.    int             redraw = 0;
  3374.    numofplanets = (unsigned char) sbuf[1];
  3375.  
  3376.    if (numofplanets > MAXPLANETS + 1)
  3377.       return;
  3378.  
  3379.    for (i = 0; i < numofplanets; i++, packet++) {
  3380.       if (packet->pnum < 0 || packet->pnum >= MAXPLANETS)
  3381.      continue;
  3382.  
  3383.       plan = &planets[packet->pnum];
  3384.       if (plan->pl_owner != packet->owner)
  3385.      redraw = 1;
  3386.       plan->pl_owner = packet->owner;
  3387.       if (plan->pl_owner < FED || plan->pl_owner > ORI)
  3388.      plan->pl_owner = NOBODY;
  3389.       if (plan->pl_info != packet->info)
  3390.      redraw = 1;
  3391.       plan->pl_info = packet->info;
  3392.       /* Redraw the planet because it was updated by server */
  3393.  
  3394.       if (plan->pl_flags != (int) ntohs(packet->flags))
  3395.      redraw = 1;
  3396.       plan->pl_flags = (int) ntohs(packet->flags);
  3397.  
  3398.       if (plan->pl_armies != (unsigned char) packet->armies) {
  3399. #ifdef EM
  3400.      /*
  3401.       * don't redraw when armies change unless it crosses the '4' * army
  3402.       * limit. Keeps people from watching for planet 'flicker' * when
  3403.       * players are beaming
  3404.       */
  3405.      int             planetarmies = (unsigned char) packet->armies;
  3406.      if ((plan->pl_armies < 5 && planetarmies > 4) ||
  3407.          (plan->pl_armies > 4 && planetarmies < 5))
  3408. #endif
  3409.         redraw = 1;
  3410.       }
  3411.       plan->pl_armies = (unsigned char) packet->armies;
  3412.       if (plan->pl_info == 0) {
  3413.      plan->pl_owner = NOBODY;
  3414.       }
  3415.       if (redraw)
  3416.      plan->pl_flags |= (PLREDRAW|PLCLEAR);
  3417.  
  3418.    }                /* FOR */
  3419. }
  3420.  
  3421. sendShortReq(state)
  3422.     char            state;
  3423. {
  3424.    struct shortreq_cpacket shortReq;
  3425.  
  3426.    shortReq.type = CP_S_REQ;
  3427.    shortReq.req = state;
  3428.    shortReq.version = SHORTVERSION;
  3429.    switch (state) {
  3430.    case SPK_VON:
  3431.       warning("Sending short packet request");
  3432.       break;
  3433.    case SPK_VOFF:
  3434.       warning("Sending old packet request");
  3435.       break;
  3436.    default:
  3437.       break;
  3438.    }
  3439.    if ((state == SPK_SALL || state == SPK_ALL) && recv_short) {
  3440.       /* Let the client do the work, and not the network :-) */
  3441.  
  3442.       register int    i;
  3443.       for (i = 0; i < MAXPLAYER * MAXTORP; i++)
  3444.      torps[i].t_status = TFREE;
  3445.  
  3446.       for (i = 0; i < MAXPLAYER * MAXPLASMA; i++)
  3447.      plasmatorps[i].pt_status = PTFREE;
  3448.  
  3449.       for (i = 0; i < MAXPLAYER; i++) {
  3450.      players[i].p_ntorp = 0;
  3451.      players[i].p_nplasmatorp = 0;
  3452.      phasers[i].ph_status = PHFREE;
  3453.       }
  3454.       warning("Sent request for small update");
  3455.    }
  3456.    sendServerPacket((struct shortreq_cpacket *) & shortReq);
  3457. }
  3458. #endif
  3459.  
  3460. #ifdef PACKET_LOG
  3461. static int                      Max_CPS = 0;
  3462. static int                      Max_CPSout = 0;
  3463. static time_t                   Start_Time = 0;
  3464. static double                   s2 = 0;
  3465. static int                      sumpl = 0;
  3466. static int                      numpl = 0;
  3467. static int                      outdata_this_sec = 0;
  3468. static double                   sout2 = 0;
  3469. static int                      sumout = 0;
  3470. /* HW clumsy but who cares ... :-) */
  3471. static int                      vari_sizes[NUM_PACKETS];
  3472. static int                      cp_msg_size;    /* For CP_S_MESSAGE */
  3473.  
  3474. int 
  3475. Log_Packet(type, act_size)
  3476.    char                            type;
  3477.    int                             act_size;    /* HW */
  3478. {
  3479.    static time_t                   lasttime;
  3480.    static int                      data_this_sec;
  3481.    time_t                          this_sec;
  3482.    if (log_packets == 0)
  3483.       return;
  3484.  
  3485.    if (type <= 0 && type > NUM_PACKETS) {
  3486.       fprintf(stderr, "Attempted to log a bad packet? \n");
  3487.       return;
  3488.    }
  3489.    packet_log[type]++;
  3490.    /*data_this_sec += handlers[type].size;*/
  3491.    data_this_sec += act_size;    /* HW */
  3492.    ALL_BYTES += act_size;    /* To get all bytes */
  3493.    if (handlers[type].size == -1) {    /* vari packet */
  3494.       vari_sizes[type] += act_size;
  3495.    }
  3496.    this_sec = time(NULL);
  3497.    if (this_sec != lasttime) {
  3498.       lasttime = this_sec;
  3499.       if (log_packets > 1) {
  3500.      fprintf(stdout, "%d %d %d\n", this_sec - Start_Time, data_this_sec, outdata_this_sec);
  3501.       }
  3502.       if (Start_Time == 0) {
  3503.      Start_Time = this_sec;
  3504.       }
  3505.       /* ignore baudage on the first few seconds of reception --
  3506.       ** that's when we get crushed by the motd being sent */
  3507.       if (lasttime > Start_Time + 10) {
  3508.      if (data_this_sec > Max_CPS)
  3509.         Max_CPS = data_this_sec;
  3510.      if (outdata_this_sec > Max_CPSout)
  3511.         Max_CPSout = outdata_this_sec;
  3512.      sumpl += data_this_sec;
  3513.      s2 += (data_this_sec * data_this_sec);
  3514.      sout2 += outdata_this_sec * outdata_this_sec;
  3515.      sumout += outdata_this_sec;
  3516.      numpl++;
  3517.       }
  3518.       data_this_sec = 0;
  3519.       outdata_this_sec = 0;
  3520.    }
  3521. }
  3522.  
  3523. int 
  3524. Log_OPacket(tpe, size)
  3525.    int                             tpe;
  3526.    int                             size;
  3527. {
  3528.    /* Log Packet will handle the per second resets of this */
  3529.    if (log_packets == 0)
  3530.       return;
  3531.    outpacket_log[tpe]++;
  3532.    outdata_this_sec += size;
  3533. #ifdef SHORT_PACKETS
  3534.    if (tpe == CP_S_MESSAGE)
  3535.       cp_msg_size += size;    /* HW */
  3536. #endif
  3537. }
  3538. /* print out out the cool information on packet logging */
  3539. Dump_Packet_Log_Info()
  3540. {
  3541.    int                             i;
  3542.    time_t                          Now;
  3543.    int                             total_bytes = 0;
  3544.    int                             outtotal_bytes = 0;
  3545.    int                             calc_temp;
  3546.    Now = time(NULL);
  3547.  
  3548.    printf("Packet Logging Summary:\n");
  3549.    printf("Start time: %s ", ctime(&Start_Time));
  3550.    printf(" End time: %s Elapsed play time: %3.2f min\n",
  3551.       ctime(&Now), (float) ((Now - Start_Time) / 60));
  3552.    printf("Maximum CPS in during normal play: %d bytes per sec\n", Max_CPS);
  3553.    printf("Standard deviation in: %d\n",
  3554.       (int) sqrt((numpl * s2 - sumpl * sumpl) / (numpl * (numpl - 1))));
  3555.    printf("Maximum CPS out during normal play: %d bytes per sec\n", Max_CPSout);
  3556.    printf("Standard deviation out: %d\n",
  3557.       (int) sqrt((numpl * sout2 - sumout * sumout) / (numpl * (numpl - 1))));
  3558.  
  3559. #ifdef SHORT_PACKETS
  3560.    /*total_bytes = ALL_BYTES;*//* Hope this works  HW */
  3561.    for (i = 0; i <= NUM_PACKETS; i++) {    /* I think it must be <= */
  3562.       if (handlers[i].size != -1)
  3563.      total_bytes += handlers[i].size * packet_log[i];
  3564.       else
  3565.      total_bytes += vari_sizes[i];
  3566.    }                /* The result should be == ALL_BYTES HW */
  3567. #else
  3568.    for (i = 0; i <= NUM_PACKETS; i++) {
  3569.       total_bytes += handlers[i].size * packet_log[i];
  3570.    }
  3571. #endif
  3572.    for (i = 0; i <= NUM_SIZES; i++) {
  3573. #ifdef SHORT_PACKETS
  3574.       if (handlers[i].size != -1)
  3575.      outtotal_bytes += outpacket_log[i] * sizes[i];
  3576.       else
  3577.      outtotal_bytes += cp_msg_size;    /* HW */
  3578. #else
  3579.       outtotal_bytes += outpacket_log[i] * sizes[i];
  3580. #endif
  3581.    }
  3582.  
  3583.    printf("Total bytes received %d, average CPS: %4.1f\n",
  3584.       total_bytes, (float) (total_bytes / (Now - Start_Time)));
  3585.    printf("Server Packets Summary:\n");
  3586.    printf("Num #Rcvd    Size   TotlBytes   %Total\n");
  3587.    for (i = 0; i <= NUM_PACKETS; i++) {
  3588. #ifdef SHORT_PACKETS
  3589.       if (handlers[i].size != -1)
  3590.      calc_temp = handlers[i].size * packet_log[i];
  3591.       else
  3592.      calc_temp = vari_sizes[i];
  3593.  
  3594.       printf("%3d %5d    %4d   %9d   %3.2f\n",
  3595.          i, packet_log[i], handlers[i].size, calc_temp,
  3596.          (float) (calc_temp * 100 / total_bytes));
  3597. #else
  3598.       calc_temp = handlers[i].size * packet_log[i];
  3599.       printf("%3d %5d    %4d   %9d   %3.2f\n",
  3600.          i, packet_log[i], handlers[i].size, calc_temp,
  3601.          (float) (calc_temp * 100 / total_bytes));
  3602. #endif
  3603.    }
  3604.    printf("Total bytes sent %d, average CPS: %4.1f\n",
  3605.       outtotal_bytes, (float) (outtotal_bytes / (Now - Start_Time)));
  3606.    printf("Client Packets Summary:\n");
  3607.    printf("Num #Sent    Size   TotlBytes   %Total\n");
  3608.    for (i = 0; i <= NUM_SIZES; i++) {
  3609. #ifdef SHORT_PACKETS
  3610.       if (sizes[i] == -1)
  3611.      calc_temp = cp_msg_size;
  3612.       else
  3613.      calc_temp = sizes[i] * outpacket_log[i];
  3614.       printf("%3d %5d    %4d   %9d   %3.2f\n",
  3615.          i, outpacket_log[i], sizes[i], calc_temp,
  3616.          (float) (calc_temp * 100 / outtotal_bytes));
  3617.    }
  3618. #else
  3619.       calc_temp = sizes[i] * outpacket_log[i];
  3620.       printf("%3d %5d    %4d   %9d   %3.2f\n",
  3621.          i, outpacket_log[i], sizes[i], calc_temp,
  3622.          (float) (calc_temp * 100 / outtotal_bytes));
  3623.    }
  3624. #endif
  3625. }
  3626. #endif
  3627.